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

Code before:
    business_profile: domain::Profile,
    webhook_details: api::IncomingWebhookDetails,
    source_verified: bool,
    connector: &ConnectorEnum,
    _request_details: &IncomingWebhookRequestDetails<'_>,
    event_type: webhooks::IncomingWebhookEvent,
    billing_connector_mca_id: common_utils::id_type::MerchantConnectorAccountId,
) -> CustomResult<WebhookResponseTracker, errors::ApiErrorResponse> {
    // Only process invoice_generated events for MIT payments
    if event_type != webhooks::IncomingWebhookEvent::InvoiceGenerated {
        return Ok(WebhookResponseTracker::NoEffect);
    }

    if !source_verified {
        logger::error!("Webhook source verification failed for subscription webhook flow");
        return Err(report!(
            errors::ApiErrorResponse::WebhookAuthenticationFailed
        ));
    }

    let connector_name = connector.id().to_string();

    let connector = Connector::from_str(&connector_name)
        .change_context(errors::ConnectorError::InvalidConnectorName)
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable_lazy(|| format!("unable to parse connector name {connector_name}"))?;

    let mit_payment_data = match connector {
        Connector::Chargebee => {
            let webhook_body = ChargebeeInvoiceBody::get_invoice_webhook_data_from_body(
                &webhook_details.resource_object,
            )
            .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
            .attach_printable("Failed to parse Chargebee invoice webhook body")?;

            ChargebeeMitPaymentData::try_from(webhook_body)
                .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
                .attach_printable("Failed to extract MIT payment data from Chargebee webhook")?
        }
        _ => {
            return Err(errors::ApiErrorResponse::WebhookProcessingFailure)
                .attach_printable("Subscription webhook flow not supported for this connector");
        }
    };

    if mit_payment_data.first_invoice {
        return Ok(WebhookResponseTracker::NoEffect);
    }

    // Find subscription by merchant_id and subscription_id to get payment_method_id
    let subscription = state

Review comment (bug):
```suggestion
        .change_context(errors::ApiErrorResponse::IncorrectConnectorNameGiven)
        .attach_printable_lazy(|| format!("unable to parse connector name {connector_name}"))?;
```

Code after:
                .peek()
                .to_string(),
        ),
        mandate_metadata,
        connector_mandate_request_reference_id,
    )?;
    Ok(connector_mandate_details)
}

#[allow(clippy::too_many_arguments)]
#[instrument(skip_all)]
async fn subscription_incoming_webhook_flow(
    state: SessionState,
    _req_state: ReqState,
    merchant_context: domain::MerchantContext,
    business_profile: domain::Profile,
    _webhook_details: api::IncomingWebhookDetails,
    source_verified: bool,
    connector_enum: &ConnectorEnum,
    request_details: &IncomingWebhookRequestDetails<'_>,
    event_type: webhooks::IncomingWebhookEvent,
    billing_connector_mca_id: common_utils::id_type::MerchantConnectorAccountId,
) -> CustomResult<WebhookResponseTracker, errors::ApiErrorResponse> {
    // Only process invoice_generated events for MIT payments
    if event_type != webhooks::IncomingWebhookEvent::InvoiceGenerated {
        return Ok(WebhookResponseTracker::NoEffect);
    }

    if !source_verified {
        logger::error!("Webhook source verification failed for subscription webhook flow");
        return Err(report!(
            errors::ApiErrorResponse::WebhookAuthenticationFailed
        ));
    }

    let connector_name = connector_enum.id().to_string();

    let connector = Connector::from_str(&connector_name)
        .change_context(errors::ConnectorError::InvalidConnectorName)
        .change_context(errors::ApiErrorResponse::IncorrectConnectorNameGiven)
        .attach_printable_lazy(|| format!("unable to parse connector name {connector_name}"))?;

    let mit_payment_data = connector_enum
        .get_subscription_mit_payment_data(request_details)
        .change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
        .attach_printable("Failed to extract MIT payment data from subscription webhook")?;

    if mit_payment_data.first_invoice {
        return Ok(WebhookResponseTracker::NoEffect);
    }