mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 17:19:15 +08:00
feat: Implement subscription create for Chargebee (#9303)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -16,30 +16,38 @@ use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::{revenue_recovery, router_data_v2::RouterDataV2};
|
||||
use hyperswitch_domain_models::{
|
||||
router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
|
||||
router_data_v2::flow_common_types::SubscriptionCreateData,
|
||||
router_flow_types::{
|
||||
access_token_auth::AccessTokenAuth,
|
||||
payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void},
|
||||
refunds::{Execute, RSync},
|
||||
revenue_recovery::InvoiceRecordBack,
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans, SubscriptionCreate},
|
||||
CreateConnectorCustomer,
|
||||
},
|
||||
router_request_types::{
|
||||
revenue_recovery::InvoiceRecordBackRequest,
|
||||
subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
|
||||
SubscriptionCreateRequest,
|
||||
},
|
||||
AccessTokenRequestData, ConnectorCustomerData, PaymentMethodTokenizationData,
|
||||
PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData,
|
||||
PaymentsSyncData, RefundsData, SetupMandateRequestData,
|
||||
},
|
||||
router_response_types::{
|
||||
revenue_recovery::InvoiceRecordBackResponse,
|
||||
subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
SubscriptionCreateResponse,
|
||||
},
|
||||
ConnectorInfo, PaymentsResponseData, RefundsResponseData,
|
||||
},
|
||||
types::{
|
||||
ConnectorCustomerRouterData, GetSubscriptionPlanPricesRouterData,
|
||||
GetSubscriptionPlansRouterData, InvoiceRecordBackRouterData, PaymentsAuthorizeRouterData,
|
||||
PaymentsCaptureRouterData, PaymentsSyncRouterData, RefundSyncRouterData, RefundsRouterData,
|
||||
SubscriptionCreateRouterData,
|
||||
},
|
||||
};
|
||||
use hyperswitch_interfaces::{
|
||||
@ -94,10 +102,117 @@ impl api::Refund for Chargebee {}
|
||||
impl api::RefundExecute for Chargebee {}
|
||||
impl api::RefundSync for Chargebee {}
|
||||
impl api::PaymentToken for Chargebee {}
|
||||
impl api::subscriptions::Subscriptions for Chargebee {}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
impl api::revenue_recovery::RevenueRecoveryRecordBack for Chargebee {}
|
||||
|
||||
impl api::subscriptions::SubscriptionCreate for Chargebee {}
|
||||
|
||||
impl ConnectorIntegration<SubscriptionCreate, SubscriptionCreateRequest, SubscriptionCreateResponse>
|
||||
for Chargebee
|
||||
{
|
||||
fn get_headers(
|
||||
&self,
|
||||
req: &SubscriptionCreateRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
|
||||
self.build_headers(req, connectors)
|
||||
}
|
||||
|
||||
fn get_url(
|
||||
&self,
|
||||
req: &SubscriptionCreateRouterData,
|
||||
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("{{merchant_endpoint_prefix}}", metadata.site.peek());
|
||||
let customer_id = &req.request.customer_id.get_string_repr().to_string();
|
||||
Ok(format!(
|
||||
"{url}v2/customers/{customer_id}/subscription_for_items"
|
||||
))
|
||||
}
|
||||
|
||||
fn get_content_type(&self) -> &'static str {
|
||||
self.common_get_content_type()
|
||||
}
|
||||
|
||||
fn get_request_body(
|
||||
&self,
|
||||
req: &SubscriptionCreateRouterData,
|
||||
_connectors: &Connectors,
|
||||
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||
let connector_router_data = chargebee::ChargebeeRouterData::from((MinorUnit::new(0), req));
|
||||
let connector_req =
|
||||
chargebee::ChargebeeSubscriptionCreateRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::FormUrlEncoded(Box::new(connector_req)))
|
||||
}
|
||||
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &SubscriptionCreateRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Option<Request>, errors::ConnectorError> {
|
||||
Ok(Some(
|
||||
RequestBuilder::new()
|
||||
.method(Method::Post)
|
||||
.url(&types::SubscriptionCreateType::get_url(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.attach_default_headers()
|
||||
.headers(types::SubscriptionCreateType::get_headers(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.set_body(types::SubscriptionCreateType::get_request_body(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.build(),
|
||||
))
|
||||
}
|
||||
|
||||
fn handle_response(
|
||||
&self,
|
||||
data: &SubscriptionCreateRouterData,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
res: Response,
|
||||
) -> CustomResult<SubscriptionCreateRouterData, errors::ConnectorError> {
|
||||
let response: chargebee::ChargebeeSubscriptionCreateResponse = res
|
||||
.response
|
||||
.parse_struct("chargebee ChargebeeSubscriptionCreateResponse")
|
||||
.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
|
||||
ConnectorIntegrationV2<
|
||||
SubscriptionCreate,
|
||||
SubscriptionCreateData,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
> for Chargebee
|
||||
{
|
||||
// Not Implemented (R)
|
||||
}
|
||||
|
||||
impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
|
||||
for Chargebee
|
||||
{
|
||||
@ -689,7 +804,6 @@ fn get_chargebee_plans_query_params(
|
||||
Ok(param)
|
||||
}
|
||||
|
||||
impl api::subscriptions::Subscriptions for Chargebee {}
|
||||
impl api::subscriptions::GetSubscriptionPlansFlow for Chargebee {}
|
||||
|
||||
impl
|
||||
|
||||
@ -5,7 +5,7 @@ use common_enums::enums;
|
||||
use common_utils::{
|
||||
errors::CustomResult,
|
||||
ext_traits::ByteSliceExt,
|
||||
id_type::CustomerId,
|
||||
id_type::{CustomerId, SubscriptionId},
|
||||
pii::{self, Email},
|
||||
types::MinorUnit,
|
||||
};
|
||||
@ -17,14 +17,20 @@ use hyperswitch_domain_models::{
|
||||
router_data::{ConnectorAuthType, RouterData},
|
||||
router_flow_types::{
|
||||
refunds::{Execute, RSync},
|
||||
subscriptions::SubscriptionCreate,
|
||||
CreateConnectorCustomer, InvoiceRecordBack,
|
||||
},
|
||||
router_request_types::{
|
||||
revenue_recovery::InvoiceRecordBackRequest, ConnectorCustomerData, ResponseId,
|
||||
revenue_recovery::InvoiceRecordBackRequest,
|
||||
subscriptions::{SubscriptionAutoCollection, SubscriptionCreateRequest},
|
||||
ConnectorCustomerData, ResponseId,
|
||||
},
|
||||
router_response_types::{
|
||||
revenue_recovery::InvoiceRecordBackResponse,
|
||||
subscriptions::{self, GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
|
||||
subscriptions::{
|
||||
self, GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
SubscriptionCreateResponse, SubscriptionStatus,
|
||||
},
|
||||
ConnectorCustomerResponseData, PaymentsResponseData, RefundsResponseData,
|
||||
},
|
||||
types::{InvoiceRecordBackRouterData, PaymentsAuthorizeRouterData, RefundsRouterData},
|
||||
@ -36,9 +42,158 @@ use time::PrimitiveDateTime;
|
||||
|
||||
use crate::{
|
||||
types::{RefundsResponseRouterData, ResponseRouterData},
|
||||
utils::{self, PaymentsAuthorizeRequestData},
|
||||
utils::{self, PaymentsAuthorizeRequestData, RouterData as OtherRouterData},
|
||||
};
|
||||
|
||||
// SubscriptionCreate structures
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ChargebeeSubscriptionCreateRequest {
|
||||
#[serde(rename = "id")]
|
||||
pub subscription_id: SubscriptionId,
|
||||
#[serde(rename = "subscription_items[item_price_id][0]")]
|
||||
pub item_price_id: String,
|
||||
#[serde(rename = "subscription_items[quantity][0]")]
|
||||
pub quantity: Option<u32>,
|
||||
#[serde(rename = "billing_address[line1]")]
|
||||
pub billing_address_line1: Option<Secret<String>>,
|
||||
#[serde(rename = "billing_address[city]")]
|
||||
pub billing_address_city: Option<String>,
|
||||
#[serde(rename = "billing_address[state]")]
|
||||
pub billing_address_state: Option<Secret<String>>,
|
||||
#[serde(rename = "billing_address[zip]")]
|
||||
pub billing_address_zip: Option<Secret<String>>,
|
||||
#[serde(rename = "billing_address[country]")]
|
||||
pub billing_address_country: Option<common_enums::CountryAlpha2>,
|
||||
pub auto_collection: ChargebeeAutoCollection,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ChargebeeAutoCollection {
|
||||
On,
|
||||
Off,
|
||||
}
|
||||
|
||||
impl From<SubscriptionAutoCollection> for ChargebeeAutoCollection {
|
||||
fn from(auto_collection: SubscriptionAutoCollection) -> Self {
|
||||
match auto_collection {
|
||||
SubscriptionAutoCollection::On => Self::On,
|
||||
SubscriptionAutoCollection::Off => Self::Off,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&ChargebeeRouterData<&hyperswitch_domain_models::types::SubscriptionCreateRouterData>>
|
||||
for ChargebeeSubscriptionCreateRequest
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: &ChargebeeRouterData<&hyperswitch_domain_models::types::SubscriptionCreateRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let req = &item.router_data.request;
|
||||
|
||||
let first_item =
|
||||
req.subscription_items
|
||||
.first()
|
||||
.ok_or(errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "subscription_items",
|
||||
})?;
|
||||
|
||||
Ok(Self {
|
||||
subscription_id: req.subscription_id.clone(),
|
||||
item_price_id: first_item.item_price_id.clone(),
|
||||
quantity: first_item.quantity,
|
||||
billing_address_line1: item.router_data.get_optional_billing_line1(),
|
||||
billing_address_city: item.router_data.get_optional_billing_city(),
|
||||
billing_address_state: item.router_data.get_optional_billing_state(),
|
||||
billing_address_zip: item.router_data.get_optional_billing_zip(),
|
||||
billing_address_country: item.router_data.get_optional_billing_country(),
|
||||
auto_collection: req.auto_collection.clone().into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct ChargebeeSubscriptionCreateResponse {
|
||||
pub subscription: ChargebeeSubscriptionDetails,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct ChargebeeSubscriptionDetails {
|
||||
pub id: SubscriptionId,
|
||||
pub status: ChargebeeSubscriptionStatus,
|
||||
pub customer_id: CustomerId,
|
||||
pub currency_code: enums::Currency,
|
||||
pub total_dues: Option<MinorUnit>,
|
||||
#[serde(default, with = "common_utils::custom_serde::timestamp::option")]
|
||||
pub next_billing_at: Option<PrimitiveDateTime>,
|
||||
#[serde(default, with = "common_utils::custom_serde::timestamp::option")]
|
||||
pub created_at: Option<PrimitiveDateTime>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ChargebeeSubscriptionStatus {
|
||||
Future,
|
||||
#[serde(rename = "in_trial")]
|
||||
InTrial,
|
||||
Active,
|
||||
#[serde(rename = "non_renewing")]
|
||||
NonRenewing,
|
||||
Paused,
|
||||
Cancelled,
|
||||
Transferred,
|
||||
}
|
||||
|
||||
impl From<ChargebeeSubscriptionStatus> for SubscriptionStatus {
|
||||
fn from(status: ChargebeeSubscriptionStatus) -> Self {
|
||||
match status {
|
||||
ChargebeeSubscriptionStatus::Future => Self::Pending,
|
||||
ChargebeeSubscriptionStatus::InTrial => Self::Trial,
|
||||
ChargebeeSubscriptionStatus::Active => Self::Active,
|
||||
ChargebeeSubscriptionStatus::NonRenewing => Self::Onetime,
|
||||
ChargebeeSubscriptionStatus::Paused => Self::Paused,
|
||||
ChargebeeSubscriptionStatus::Cancelled => Self::Cancelled,
|
||||
ChargebeeSubscriptionStatus::Transferred => Self::Cancelled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
TryFrom<
|
||||
ResponseRouterData<
|
||||
SubscriptionCreate,
|
||||
ChargebeeSubscriptionCreateResponse,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
>,
|
||||
> for hyperswitch_domain_models::types::SubscriptionCreateRouterData
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: ResponseRouterData<
|
||||
SubscriptionCreate,
|
||||
ChargebeeSubscriptionCreateResponse,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let subscription = &item.response.subscription;
|
||||
Ok(Self {
|
||||
response: Ok(SubscriptionCreateResponse {
|
||||
subscription_id: subscription.id.clone(),
|
||||
status: subscription.status.clone().into(),
|
||||
customer_id: subscription.customer_id.clone(),
|
||||
currency_code: subscription.currency_code,
|
||||
total_amount: subscription.total_dues.unwrap_or(MinorUnit::new(0)),
|
||||
next_billing_at: subscription.next_billing_at,
|
||||
created_at: subscription.created_at,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Fill the struct with respective fields
|
||||
pub struct ChargebeeRouterData<T> {
|
||||
pub amount: MinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
|
||||
|
||||
@ -10,17 +10,22 @@ use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::{
|
||||
router_data::{ConnectorAuthType, ErrorResponse},
|
||||
router_data_v2::{
|
||||
flow_common_types::{GetSubscriptionPlanPricesData, GetSubscriptionPlansData},
|
||||
flow_common_types::{
|
||||
GetSubscriptionPlanPricesData, GetSubscriptionPlansData, SubscriptionCreateData,
|
||||
},
|
||||
UasFlowData,
|
||||
},
|
||||
router_flow_types::{
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans, SubscriptionCreate},
|
||||
unified_authentication_service::{
|
||||
Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate,
|
||||
},
|
||||
},
|
||||
router_request_types::{
|
||||
subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
|
||||
SubscriptionCreateRequest,
|
||||
},
|
||||
unified_authentication_service::{
|
||||
UasAuthenticationRequestData, UasAuthenticationResponseData,
|
||||
UasConfirmationRequestData, UasPostAuthenticationRequestData,
|
||||
@ -28,7 +33,7 @@ use hyperswitch_domain_models::{
|
||||
},
|
||||
},
|
||||
router_response_types::subscriptions::{
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse, SubscriptionCreateResponse,
|
||||
},
|
||||
};
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
@ -168,6 +173,16 @@ impl
|
||||
> for Recurly
|
||||
{
|
||||
}
|
||||
impl api::subscriptions_v2::SubscriptionsCreateV2 for Recurly {}
|
||||
impl
|
||||
ConnectorIntegrationV2<
|
||||
SubscriptionCreate,
|
||||
SubscriptionCreateData,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
> for Recurly
|
||||
{
|
||||
}
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
impl api::revenue_recovery_v2::RevenueRecoveryRecordBackV2 for Recurly {}
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
|
||||
@ -44,10 +44,14 @@ use hyperswitch_domain_models::{
|
||||
AccessTokenAuthentication, Authenticate, AuthenticationConfirmation,
|
||||
ExternalVaultCreateFlow, ExternalVaultDeleteFlow, ExternalVaultInsertFlow,
|
||||
ExternalVaultProxy, ExternalVaultRetrieveFlow, PostAuthenticate, PreAuthenticate,
|
||||
SubscriptionCreate as SubscriptionCreateFlow,
|
||||
},
|
||||
router_request_types::{
|
||||
authentication,
|
||||
subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
|
||||
SubscriptionCreateRequest,
|
||||
},
|
||||
unified_authentication_service::{
|
||||
UasAuthenticationRequestData, UasAuthenticationResponseData,
|
||||
UasConfirmationRequestData, UasPostAuthenticationRequestData,
|
||||
@ -66,7 +70,10 @@ use hyperswitch_domain_models::{
|
||||
VerifyWebhookSourceRequestData,
|
||||
},
|
||||
router_response_types::{
|
||||
subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
SubscriptionCreateResponse,
|
||||
},
|
||||
AcceptDisputeResponse, AuthenticationResponseData, DefendDisputeResponse,
|
||||
DisputeSyncResponse, FetchDisputesResponse, GiftCardBalanceCheckResponseData,
|
||||
MandateRevokeResponseData, PaymentsResponseData, RetrieveFileResponse,
|
||||
@ -130,7 +137,10 @@ use hyperswitch_interfaces::{
|
||||
PaymentsPreAuthenticate, PaymentsPreProcessing, TaxCalculation,
|
||||
},
|
||||
revenue_recovery::RevenueRecovery,
|
||||
subscriptions::{GetSubscriptionPlanPricesFlow, GetSubscriptionPlansFlow, Subscriptions},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesFlow, GetSubscriptionPlansFlow, SubscriptionCreate,
|
||||
Subscriptions,
|
||||
},
|
||||
vault::{
|
||||
ExternalVault, ExternalVaultCreate, ExternalVaultDelete, ExternalVaultInsert,
|
||||
ExternalVaultRetrieve,
|
||||
@ -6941,6 +6951,7 @@ macro_rules! default_imp_for_subscriptions {
|
||||
($($path:ident::$connector:ident),*) => {
|
||||
$( impl Subscriptions for $path::$connector {}
|
||||
impl GetSubscriptionPlansFlow for $path::$connector {}
|
||||
impl SubscriptionCreate for $path::$connector {}
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
GetSubscriptionPlans,
|
||||
@ -6956,6 +6967,12 @@ macro_rules! default_imp_for_subscriptions {
|
||||
GetSubscriptionPlanPricesResponse
|
||||
> for $path::$connector
|
||||
{}
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
SubscriptionCreateFlow,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
> for $path::$connector {}
|
||||
)*
|
||||
};
|
||||
}
|
||||
@ -9253,3 +9270,16 @@ impl<const T: u8>
|
||||
> for connectors::DummyConnector<T>
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8> SubscriptionCreate for connectors::DummyConnector<T> {}
|
||||
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8>
|
||||
ConnectorIntegration<
|
||||
SubscriptionCreateFlow,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
> for connectors::DummyConnector<T>
|
||||
{
|
||||
}
|
||||
|
||||
@ -150,6 +150,9 @@ pub struct FilesFlowData {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InvoiceRecordBackData;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubscriptionCreateData;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GetSubscriptionPlansData;
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ pub use payments::*;
|
||||
pub use payouts::*;
|
||||
pub use refunds::*;
|
||||
pub use revenue_recovery::*;
|
||||
pub use subscriptions::*;
|
||||
pub use unified_authentication_service::*;
|
||||
pub use vault::*;
|
||||
pub use webhooks::*;
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubscriptionCreate;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GetSubscriptionPlans;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
@ -1,3 +1,28 @@
|
||||
use api_models::payments::Address;
|
||||
use common_utils::id_type;
|
||||
|
||||
use crate::connector_endpoints;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubscriptionItem {
|
||||
pub item_price_id: String,
|
||||
pub quantity: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubscriptionCreateRequest {
|
||||
pub customer_id: id_type::CustomerId,
|
||||
pub subscription_id: id_type::SubscriptionId,
|
||||
pub subscription_items: Vec<SubscriptionItem>,
|
||||
pub billing_address: Address,
|
||||
pub auto_collection: SubscriptionAutoCollection,
|
||||
pub connector_params: connector_endpoints::ConnectorParams,
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SubscriptionAutoCollection {
|
||||
On,
|
||||
Off,
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GetSubscriptionPlansRequest {
|
||||
pub limit: Option<u32>,
|
||||
|
||||
@ -1,4 +1,29 @@
|
||||
use common_enums::Currency;
|
||||
use common_utils::{id_type, types::MinorUnit};
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SubscriptionCreateResponse {
|
||||
pub subscription_id: id_type::SubscriptionId,
|
||||
pub status: SubscriptionStatus,
|
||||
pub customer_id: id_type::CustomerId,
|
||||
pub currency_code: Currency,
|
||||
pub total_amount: MinorUnit,
|
||||
pub next_billing_at: Option<PrimitiveDateTime>,
|
||||
pub created_at: Option<PrimitiveDateTime>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SubscriptionStatus {
|
||||
Pending,
|
||||
Trial,
|
||||
Active,
|
||||
Paused,
|
||||
Unpaid,
|
||||
Onetime,
|
||||
Cancelled,
|
||||
Failed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GetSubscriptionPlansResponse {
|
||||
@ -21,7 +46,7 @@ pub struct GetSubscriptionPlanPricesResponse {
|
||||
pub struct SubscriptionPlanPrices {
|
||||
pub price_id: String,
|
||||
pub plan_id: Option<String>,
|
||||
pub amount: common_utils::types::MinorUnit,
|
||||
pub amount: MinorUnit,
|
||||
pub currency: Currency,
|
||||
pub interval: PeriodUnit,
|
||||
pub interval_count: i64,
|
||||
|
||||
@ -6,7 +6,7 @@ use crate::{
|
||||
router_flow_types::{
|
||||
mandate_revoke::MandateRevoke,
|
||||
revenue_recovery::InvoiceRecordBack,
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans, SubscriptionCreate},
|
||||
AccessTokenAuth, AccessTokenAuthentication, Authenticate, AuthenticationConfirmation,
|
||||
Authorize, AuthorizeSessionToken, BillingConnectorInvoiceSync,
|
||||
BillingConnectorPaymentsSync, CalculateTax, Capture, CompleteAuthorize,
|
||||
@ -20,7 +20,10 @@ use crate::{
|
||||
BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest,
|
||||
InvoiceRecordBackRequest,
|
||||
},
|
||||
subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
|
||||
SubscriptionCreateRequest,
|
||||
},
|
||||
unified_authentication_service::{
|
||||
UasAuthenticationRequestData, UasAuthenticationResponseData,
|
||||
UasConfirmationRequestData, UasPostAuthenticationRequestData,
|
||||
@ -42,7 +45,10 @@ use crate::{
|
||||
BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse,
|
||||
InvoiceRecordBackResponse,
|
||||
},
|
||||
subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
SubscriptionCreateResponse,
|
||||
},
|
||||
GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData,
|
||||
RefundsResponseData, TaxCalculationResponseData, VaultResponseData,
|
||||
VerifyWebhookSourceResponseData,
|
||||
@ -195,3 +201,6 @@ pub type ExternalVaultProxyPaymentsRouterDataV2 = RouterDataV2<
|
||||
ExternalVaultProxyPaymentsData,
|
||||
PaymentsResponseData,
|
||||
>;
|
||||
|
||||
pub type SubscriptionCreateRouterData =
|
||||
RouterData<SubscriptionCreate, SubscriptionCreateRequest, SubscriptionCreateResponse>;
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
//! Subscriptions Interface for V1
|
||||
#[cfg(feature = "v1")]
|
||||
use hyperswitch_domain_models::{
|
||||
router_flow_types::subscriptions::SubscriptionCreate as SubscriptionCreateFlow,
|
||||
router_flow_types::subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
|
||||
router_request_types::subscriptions::{
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest, SubscriptionCreateRequest,
|
||||
},
|
||||
router_response_types::subscriptions::{
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse, SubscriptionCreateResponse,
|
||||
},
|
||||
};
|
||||
|
||||
@ -37,12 +38,20 @@ pub trait GetSubscriptionPlanPricesFlow:
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
/// trait SubscriptionCreate
|
||||
pub trait SubscriptionCreate:
|
||||
ConnectorIntegration<SubscriptionCreateFlow, SubscriptionCreateRequest, SubscriptionCreateResponse>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait Subscriptions
|
||||
#[cfg(feature = "v1")]
|
||||
pub trait Subscriptions:
|
||||
ConnectorCommon
|
||||
+ GetSubscriptionPlansFlow
|
||||
+ GetSubscriptionPlanPricesFlow
|
||||
+ SubscriptionCreate
|
||||
+ PaymentsConnectorCustomer
|
||||
{
|
||||
}
|
||||
@ -62,3 +71,7 @@ pub trait GetSubscriptionPlanPricesFlow {}
|
||||
#[cfg(not(feature = "v1"))]
|
||||
/// trait CreateCustomer (disabled when not V1)
|
||||
pub trait ConnectorCustomer {}
|
||||
|
||||
/// trait SubscriptionCreate
|
||||
#[cfg(not(feature = "v1"))]
|
||||
pub trait SubscriptionCreate {}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
//! SubscriptionsV2
|
||||
use hyperswitch_domain_models::{
|
||||
router_data_v2::flow_common_types::{GetSubscriptionPlanPricesData, GetSubscriptionPlansData},
|
||||
router_flow_types::subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
|
||||
router_data_v2::flow_common_types::{
|
||||
GetSubscriptionPlanPricesData, GetSubscriptionPlansData, SubscriptionCreateData,
|
||||
},
|
||||
router_flow_types::subscriptions::{
|
||||
GetSubscriptionPlanPrices, GetSubscriptionPlans, SubscriptionCreate,
|
||||
},
|
||||
router_request_types::subscriptions::{
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest, SubscriptionCreateRequest,
|
||||
},
|
||||
router_response_types::subscriptions::{
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse, SubscriptionCreateResponse,
|
||||
},
|
||||
};
|
||||
|
||||
@ -15,7 +19,7 @@ use crate::connector_integration_v2::ConnectorIntegrationV2;
|
||||
|
||||
/// trait SubscriptionsV2
|
||||
pub trait SubscriptionsV2:
|
||||
GetSubscriptionPlansV2 + ConnectorCustomerV2 + GetSubscriptionPlanPricesV2
|
||||
GetSubscriptionPlansV2 + SubscriptionsCreateV2 + ConnectorCustomerV2 + GetSubscriptionPlanPricesV2
|
||||
{
|
||||
}
|
||||
|
||||
@ -40,3 +44,14 @@ pub trait GetSubscriptionPlanPricesV2:
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait SubscriptionsCreateV2
|
||||
pub trait SubscriptionsCreateV2:
|
||||
ConnectorIntegrationV2<
|
||||
SubscriptionCreate,
|
||||
SubscriptionCreateData,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@ use hyperswitch_domain_models::{
|
||||
BillingConnectorPaymentsSyncFlowData, DisputesFlowData, ExternalAuthenticationFlowData,
|
||||
ExternalVaultProxyFlowData, FilesFlowData, GetSubscriptionPlanPricesData,
|
||||
GetSubscriptionPlansData, GiftCardBalanceCheckFlowData, InvoiceRecordBackData,
|
||||
MandateRevokeFlowData, PaymentFlowData, RefundFlowData, UasFlowData,
|
||||
VaultConnectorFlowData, WebhookSourceVerifyData,
|
||||
MandateRevokeFlowData, PaymentFlowData, RefundFlowData, SubscriptionCreateData,
|
||||
UasFlowData, VaultConnectorFlowData, WebhookSourceVerifyData,
|
||||
},
|
||||
RouterDataV2,
|
||||
},
|
||||
@ -878,6 +878,7 @@ macro_rules! default_router_data_conversion {
|
||||
}
|
||||
default_router_data_conversion!(GetSubscriptionPlansData);
|
||||
default_router_data_conversion!(GetSubscriptionPlanPricesData);
|
||||
default_router_data_conversion!(SubscriptionCreateData);
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for UasFlowData {
|
||||
fn from_old_router_data(
|
||||
|
||||
@ -16,7 +16,7 @@ use hyperswitch_domain_models::{
|
||||
},
|
||||
refunds::{Execute, RSync},
|
||||
revenue_recovery::{BillingConnectorPaymentsSync, InvoiceRecordBack},
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
|
||||
subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans, SubscriptionCreate},
|
||||
unified_authentication_service::{
|
||||
Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate,
|
||||
},
|
||||
@ -32,7 +32,10 @@ use hyperswitch_domain_models::{
|
||||
BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest,
|
||||
InvoiceRecordBackRequest,
|
||||
},
|
||||
subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
|
||||
SubscriptionCreateRequest,
|
||||
},
|
||||
unified_authentication_service::{
|
||||
UasAuthenticationRequestData, UasAuthenticationResponseData,
|
||||
UasConfirmationRequestData, UasPostAuthenticationRequestData,
|
||||
@ -57,7 +60,10 @@ use hyperswitch_domain_models::{
|
||||
BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse,
|
||||
InvoiceRecordBackResponse,
|
||||
},
|
||||
subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
|
||||
subscriptions::{
|
||||
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
|
||||
SubscriptionCreateResponse,
|
||||
},
|
||||
AcceptDisputeResponse, DefendDisputeResponse, DisputeSyncResponse, FetchDisputesResponse,
|
||||
GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData,
|
||||
RefundsResponseData, RetrieveFileResponse, SubmitEvidenceResponse,
|
||||
@ -303,6 +309,13 @@ pub type InvoiceRecordBackType = dyn ConnectorIntegration<
|
||||
InvoiceRecordBackResponse,
|
||||
>;
|
||||
|
||||
/// Type alias for `ConnectorIntegration<SubscriptionCreate, SubscriptionCreateRequest, SubscriptionCreateResponse>`
|
||||
pub type SubscriptionCreateType = dyn ConnectorIntegration<
|
||||
SubscriptionCreate,
|
||||
SubscriptionCreateRequest,
|
||||
SubscriptionCreateResponse,
|
||||
>;
|
||||
|
||||
/// Type alias for `ConnectorIntegration<BillingConnectorPaymentsSync, BillingConnectorPaymentsSyncRequest, BillingConnectorPaymentsSyncResponse>`
|
||||
pub type BillingConnectorPaymentsSyncType = dyn ConnectorIntegration<
|
||||
BillingConnectorPaymentsSync,
|
||||
|
||||
@ -211,6 +211,9 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub type BoxedSubscriptionConnectorIntegrationInterface<T, Req, Res> =
|
||||
BoxedConnectorIntegrationInterface<T, common_types::SubscriptionCreateData, Req, Res>;
|
||||
|
||||
/// Handle the flow by interacting with connector module
|
||||
/// `connector_request` is applicable only in case if the `CallConnectorAction` is `Trigger`
|
||||
/// In other cases, It will be created if required, even if it is not passed
|
||||
|
||||
Reference in New Issue
Block a user