Repository: juspay/hyperswitch
File: crates/router/src/core/subscription.rs (Rust)

Code before:
        hyperswitch_domain_models::router_request_types::subscriptions::GetSubscriptionPlansRequest,
        hyperswitch_domain_models::router_response_types::subscriptions::GetSubscriptionPlansResponse,
        > = connector_data.connector.get_connector_integration();

    let get_plans_request =
        hyperswitch_domain_models::router_request_types::subscriptions::GetSubscriptionPlansRequest::default();

    let payment_id = common_utils::id_type::PaymentId::wrap("NA".to_string())
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Unable to nullify payment_id")?;

    let router_data = utils::create_subscription_router_data::<
        hyperswitch_domain_models::router_flow_types::subscriptions::GetSubscriptionPlans,
        hyperswitch_domain_models::router_request_types::subscriptions::GetSubscriptionPlansRequest,
        hyperswitch_domain_models::router_response_types::subscriptions::GetSubscriptionPlansResponse,
    >(
        &state,
        subscription.merchant_id.to_owned(),
        Some(subscription.customer_id.to_owned()),
        connector.clone(),
        auth_type.clone(),
        get_plans_request,
        payment_id
    )?;

    let response = crate::services::api::execute_connector_processing_step::<
        hyperswitch_domain_models::router_flow_types::subscriptions::GetSubscriptionPlans,
        _,
        hyperswitch_domain_models::router_request_types::subscriptions::GetSubscriptionPlansRequest,
        hyperswitch_domain_models::router_response_types::subscriptions::GetSubscriptionPlansResponse,
    >(
        &state,
        connector_integration_for_get_subscription_plans,
        &router_data,
        common_enums::CallConnectorAction::Trigger,
        None,
        None,
    )
    .await
    .change_context(errors::ApiErrorResponse::InternalServerError)
    .attach_printable("Failed while handling response of subscription_create")?;

    let get_plans_response = response.response.map_err(|err| {
        crate::logger::error!(?err);
        errors::ApiErrorResponse::InternalServerError
    })?;

    let plans: Vec<subscription_types::GetPlansResponse> = get_plans_response
        .list
        .clone()
        .into_iter()

Review comment (suggestion):
Use billing handler to connect with processor for any processor related action and use subscription handler for all the subscription related actions.
 
Take a look at the subscription confirm PR for reference 


Code after:
            description: plan.description.clone(),
            price_id: plan_price_response
                .list
                .into_iter()
                .map(subscription_types::SubscriptionPlanPrices::from)
                .collect::<Vec<_>>(),
        })
    }

    Ok(ApplicationResponse::Json(response))
}

/// Creates and confirms a subscription in one operation.
/// This method combines the creation and confirmation flow to reduce API calls
pub async fn create_and_confirm_subscription(
    state: SessionState,
    merchant_context: MerchantContext,
    profile_id: common_utils::id_type::ProfileId,
    request: subscription_types::CreateAndConfirmSubscriptionRequest,
) -> RouterResponse<subscription_types::ConfirmSubscriptionResponse> {
    let subscription_id = common_utils::id_type::SubscriptionId::generate();

    let profile =
        SubscriptionHandler::find_business_profile(&state, &merchant_context, &profile_id)
            .await
            .attach_printable("subscriptions: failed to find business profile")?;
    let customer =
        SubscriptionHandler::find_customer(&state, &merchant_context, &request.customer_id)
            .await
            .attach_printable("subscriptions: failed to find customer")?;

    let billing_handler = BillingHandler::create(
        &state,
        merchant_context.get_merchant_account(),
        merchant_context.get_merchant_key_store(),
        Some(customer),
        profile.clone(),
    )
    .await?;
    let subscription_handler = SubscriptionHandler::new(&state, &merchant_context);
    let mut subs_handler = subscription_handler
        .create_subscription_entry(
            subscription_id.clone(),
            &request.customer_id,
            billing_handler.connector_data.connector_name,
            billing_handler.merchant_connector_id.clone(),
            request.merchant_reference_id.clone(),
            &profile.clone(),
        )
        .await
        .attach_printable("subscriptions: failed to create subscription entry")?;