fix(RevenueRecovery): Skip record-back for failed invoices on auto-voiding billing connectors (#8548)

Co-authored-by: Aniket Burman <aniket.burman@Aniket-Burman-JDXHW2PH34.local>
Co-authored-by: Nishanth Challa <nishanth.challa@Nishanth-Challa-C0WGKCFHLF.local>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Aniket Burman <aniket.burman@192.168.1.3>
Co-authored-by: Gnanasundari24 <118818938+Gnanasundari24@users.noreply.github.com>
This commit is contained in:
Aniket Burman
2025-08-01 16:00:52 +05:30
committed by GitHub
parent e6268d6d5e
commit 82cf2cb146
3 changed files with 10 additions and 49 deletions

View File

@ -597,7 +597,7 @@ impl
connectors: &Connectors,
) -> CustomResult<String, errors::ConnectorError> {
Ok(format!(
"{}v1/payment_intents/{}?expand[0]=latest_charge",
"{}v1/charges/{}",
self.base_url(connectors),
req.request.billing_connector_psync_id
))
@ -630,10 +630,10 @@ impl
recovery_router_data_types::BillingConnectorPaymentsSyncRouterData,
errors::ConnectorError,
> {
let response: stripebilling::StripebillingBillingConnectorPaymentSyncResponseData = res
let response: stripebilling::StripebillingRecoveryDetailsData = res
.response
.parse_struct::<stripebilling::StripebillingBillingConnectorPaymentSyncResponseData>(
"StripebillingBillingConnectorPaymentSyncResponseData",
.parse_struct::<stripebilling::StripebillingRecoveryDetailsData>(
"StripebillingRecoveryDetailsData",
)
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
@ -805,9 +805,7 @@ impl webhooks::IncomingWebhook for Stripebilling {
stripebilling::StripebillingWebhookBody::get_webhook_object_from_body(request.body)
.change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?;
Ok(api_models::webhooks::ObjectReferenceId::PaymentId(
api_models::payments::PaymentIdType::ConnectorTransactionId(
webhook.data.object.payment_intent,
),
api_models::payments::PaymentIdType::ConnectorTransactionId(webhook.data.object.charge),
))
}

View File

@ -426,12 +426,7 @@ impl TryFrom<StripebillingInvoiceBody> for revenue_recovery::RevenueRecoveryInvo
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StripebillingBillingConnectorPaymentSyncResponseData {
pub latest_charge: StripebillingLatestChargeData,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StripebillingLatestChargeData {
pub struct StripebillingRecoveryDetailsData {
#[serde(rename = "id")]
pub charge_id: String,
pub status: StripebillingChargeStatus,
@ -517,7 +512,7 @@ impl
TryFrom<
ResponseRouterData<
recovery_router_flows::BillingConnectorPaymentsSync,
StripebillingBillingConnectorPaymentSyncResponseData,
StripebillingRecoveryDetailsData,
recovery_request_types::BillingConnectorPaymentsSyncRequest,
recovery_response_types::BillingConnectorPaymentsSyncResponse,
>,
@ -527,12 +522,12 @@ impl
fn try_from(
item: ResponseRouterData<
recovery_router_flows::BillingConnectorPaymentsSync,
StripebillingBillingConnectorPaymentSyncResponseData,
StripebillingRecoveryDetailsData,
recovery_request_types::BillingConnectorPaymentsSyncRequest,
recovery_response_types::BillingConnectorPaymentsSyncResponse,
>,
) -> Result<Self, Self::Error> {
let charge_details = item.response.latest_charge;
let charge_details = item.response;
let merchant_reference_id =
id_type::PaymentReferenceId::from_str(charge_details.invoice_id.as_str())
.change_context(errors::ConnectorError::MissingRequiredField {

View File

@ -192,18 +192,6 @@ impl RevenueRecoveryPaymentsAttemptStatus {
db.as_scheduler()
.retry_process(process_tracker.clone(), schedule_time)
.await?;
} else {
// Record a failure transaction back to Billing Connector
// TODO: Add support for retrying failed outgoing recordback webhooks
record_back_to_billing_connector(
state,
&payment_attempt,
payment_intent,
&revenue_recovery_payment_data.billing_mca,
)
.await
.change_context(errors::RecoveryError::RecordBackToBillingConnectorFailed)
.attach_printable("Failed to record back the billing connector")?;
}
}
Self::Processing => {
@ -504,17 +492,8 @@ impl Action {
.await
.change_context(errors::RecoveryError::ProcessTrackerFailure)
.attach_printable("Failed to update the process tracker")?;
// Record back to billing connector for terminal status
// TODO: Add support for retrying failed outgoing recordback webhooks
record_back_to_billing_connector(
state,
payment_attempt,
payment_intent,
&revenue_recovery_payment_data.billing_mca,
)
.await
.change_context(errors::RecoveryError::RecordBackToBillingConnectorFailed)
.attach_printable("Failed to record back the billing connector")?;
Ok(())
}
Self::SuccessfulPayment(payment_attempt) => {
@ -702,18 +681,7 @@ impl Action {
}
Self::TerminalFailure(payment_attempt) => {
// Record a failure transaction back to Billing Connector
// TODO: Add support for retrying failed outgoing recordback webhooks
record_back_to_billing_connector(
state,
payment_attempt,
payment_intent,
&revenue_recovery_payment_data.billing_mca,
)
.await
.change_context(errors::RecoveryError::RecordBackToBillingConnectorFailed)
.attach_printable("Failed to record back the billing connector")?;
// finish the current psync task
db.as_scheduler()
.finish_process_with_business_status(