mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 03:13:56 +08:00
feat(subscription): Add endpoint to get Subscription estimate (#9637)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Gaurav Rawat <104276743+GauravRawat369@users.noreply.github.com>
This commit is contained in:
@ -422,3 +422,27 @@ pub async fn get_subscription(
|
||||
subscription.to_subscription_response(),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn get_estimate(
|
||||
state: SessionState,
|
||||
merchant_context: MerchantContext,
|
||||
profile_id: common_utils::id_type::ProfileId,
|
||||
query: subscription_types::EstimateSubscriptionQuery,
|
||||
) -> RouterResponse<subscription_types::EstimateSubscriptionResponse> {
|
||||
let profile =
|
||||
SubscriptionHandler::find_business_profile(&state, &merchant_context, &profile_id)
|
||||
.await
|
||||
.attach_printable("subscriptions: failed to find business profile in get_estimate")?;
|
||||
let billing_handler = BillingHandler::create(
|
||||
&state,
|
||||
merchant_context.get_merchant_account(),
|
||||
merchant_context.get_merchant_key_store(),
|
||||
None,
|
||||
profile,
|
||||
)
|
||||
.await?;
|
||||
let estimate = billing_handler
|
||||
.get_subscription_estimate(&state, query)
|
||||
.await?;
|
||||
Ok(ApplicationResponse::Json(estimate.into()))
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@ use common_utils::{ext_traits::ValueExt, pii};
|
||||
use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::{
|
||||
router_data_v2::flow_common_types::{
|
||||
GetSubscriptionPlanPricesData, GetSubscriptionPlansData, InvoiceRecordBackData,
|
||||
SubscriptionCreateData, SubscriptionCustomerData,
|
||||
GetSubscriptionEstimateData, GetSubscriptionPlanPricesData, GetSubscriptionPlansData,
|
||||
InvoiceRecordBackData, SubscriptionCreateData, SubscriptionCustomerData,
|
||||
},
|
||||
router_request_types::{
|
||||
revenue_recovery::InvoiceRecordBackRequest, subscriptions as subscription_request_types,
|
||||
@ -20,7 +20,10 @@ use hyperswitch_domain_models::{
|
||||
|
||||
use super::errors;
|
||||
use crate::{
|
||||
core::payments as payments_core, routes::SessionState, services, types::api as api_types,
|
||||
core::{payments as payments_core, subscription::subscription_types},
|
||||
routes::SessionState,
|
||||
services,
|
||||
types::api as api_types,
|
||||
};
|
||||
|
||||
pub struct BillingHandler {
|
||||
@ -283,6 +286,45 @@ impl BillingHandler {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_subscription_estimate(
|
||||
&self,
|
||||
state: &SessionState,
|
||||
estimate_request: subscription_types::EstimateSubscriptionQuery,
|
||||
) -> errors::RouterResult<subscription_response_types::GetSubscriptionEstimateResponse> {
|
||||
let estimate_req = subscription_request_types::GetSubscriptionEstimateRequest {
|
||||
price_id: estimate_request.item_price_id.clone(),
|
||||
};
|
||||
|
||||
let router_data = self.build_router_data(
|
||||
state,
|
||||
estimate_req,
|
||||
GetSubscriptionEstimateData {
|
||||
connector_meta_data: self.connector_metadata.clone(),
|
||||
},
|
||||
)?;
|
||||
let connector_integration = self.connector_data.connector.get_connector_integration();
|
||||
|
||||
let response = Box::pin(self.call_connector(
|
||||
state,
|
||||
router_data,
|
||||
"get subscription estimate from connector",
|
||||
connector_integration,
|
||||
))
|
||||
.await?;
|
||||
|
||||
match response {
|
||||
Ok(response_data) => Ok(response_data),
|
||||
Err(err) => Err(errors::ApiErrorResponse::ExternalConnectorError {
|
||||
code: err.code,
|
||||
message: err.message,
|
||||
connector: self.connector_data.connector_name.to_string(),
|
||||
status_code: err.status_code,
|
||||
reason: err.reason,
|
||||
}
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_subscription_plans(
|
||||
&self,
|
||||
state: &SessionState,
|
||||
|
||||
@ -1187,6 +1187,7 @@ impl Subscription {
|
||||
subscription::create_subscription(state, req, payload)
|
||||
}),
|
||||
))
|
||||
.service(web::resource("/estimate").route(web::get().to(subscription::get_estimate)))
|
||||
.service(
|
||||
web::resource("/plans").route(web::get().to(subscription::get_subscription_plans)),
|
||||
)
|
||||
|
||||
@ -91,6 +91,7 @@ impl From<Flow> for ApiIdentifier {
|
||||
| Flow::ConfirmSubscription
|
||||
| Flow::CreateAndConfirmSubscription
|
||||
| Flow::GetSubscription
|
||||
| Flow::GetSubscriptionEstimate
|
||||
| Flow::GetPlansForSubscription => Self::Subscription,
|
||||
Flow::RetrieveForexFlow => Self::Forex,
|
||||
Flow::AddToBlocklist => Self::Blocklist,
|
||||
|
||||
@ -7,6 +7,7 @@ use std::str::FromStr;
|
||||
|
||||
use actix_web::{web, HttpRequest, HttpResponse, Responder};
|
||||
use api_models::subscription as subscription_types;
|
||||
use error_stack::report;
|
||||
use hyperswitch_domain_models::errors;
|
||||
use router_env::{
|
||||
tracing::{self, instrument},
|
||||
@ -252,3 +253,40 @@ pub async fn create_and_confirm_subscription(
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
/// add support for get subscription estimate
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_estimate(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
query: web::Query<subscription_types::EstimateSubscriptionQuery>,
|
||||
) -> impl Responder {
|
||||
let flow = Flow::GetSubscriptionEstimate;
|
||||
let profile_id = match extract_profile_id(&req) {
|
||||
Ok(id) => id,
|
||||
Err(response) => return response,
|
||||
};
|
||||
let api_auth = auth::ApiKeyAuth {
|
||||
is_connected_allowed: false,
|
||||
is_platform_allowed: false,
|
||||
};
|
||||
let (auth_type, _auth_flow) = match auth::get_auth_type_and_flow(req.headers(), api_auth) {
|
||||
Ok(auth) => auth,
|
||||
Err(err) => return oss_api::log_and_return_error_response(report!(err)),
|
||||
};
|
||||
Box::pin(oss_api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
query.into_inner(),
|
||||
|state, auth: auth::AuthenticationData, query, _| {
|
||||
let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
|
||||
domain::Context(auth.merchant_account, auth.key_store),
|
||||
));
|
||||
subscription::get_estimate(state, merchant_context, profile_id.clone(), query)
|
||||
},
|
||||
&*auth_type,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user