feat: Add outgoing webhooks for subscriptions (#9859)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Jagan Elavarasan <jaganelavarasan@gmail.com>
This commit is contained in:
Sarthak Soni
2025-10-27 15:24:12 +05:30
committed by GitHub
parent 6ff2116461
commit 62035c4aeb
27 changed files with 600 additions and 137 deletions

View File

@ -1504,6 +1504,29 @@ impl Currency {
}
}
#[derive(
Clone,
Copy,
Debug,
Eq,
PartialEq,
serde::Deserialize,
serde::Serialize,
strum::Display,
strum::EnumString,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum EventObjectType {
PaymentDetails,
RefundDetails,
DisputeDetails,
MandateDetails,
PayoutDetails,
SubscriptionDetails,
}
#[derive(
Clone,
Copy,
@ -1527,6 +1550,7 @@ pub enum EventClass {
Mandates,
#[cfg(feature = "payouts")]
Payouts,
Subscriptions,
}
impl EventClass {
@ -1565,6 +1589,7 @@ impl EventClass {
EventType::PayoutExpired,
EventType::PayoutReversed,
]),
Self::Subscriptions => HashSet::from([EventType::InvoicePaid]),
}
}
}
@ -1624,6 +1649,7 @@ pub enum EventType {
PayoutExpired,
#[cfg(feature = "payouts")]
PayoutReversed,
InvoicePaid,
}
#[derive(
@ -9781,3 +9807,49 @@ impl From<IntentStatus> for InvoiceStatus {
}
}
}
/// Possible states of a subscription lifecycle.
///
/// - `Created`: Subscription was created but not yet activated.
/// - `Active`: Subscription is currently active.
/// - `InActive`: Subscription is inactive.
/// - `Pending`: Subscription is pending activation.
/// - `Trial`: Subscription is in a trial period.
/// - `Paused`: Subscription is paused.
/// - `Unpaid`: Subscription is unpaid.
/// - `Onetime`: Subscription is a one-time payment.
/// - `Cancelled`: Subscription has been cancelled.
/// - `Failed`: Subscription has failed.
#[derive(
Debug,
Clone,
Copy,
serde::Serialize,
strum::EnumString,
strum::Display,
strum::EnumIter,
ToSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum SubscriptionStatus {
/// Subscription is active.
Active,
/// Subscription is created but not yet active.
Created,
/// Subscription is inactive.
InActive,
/// Subscription is in pending state.
Pending,
/// Subscription is in trial state.
Trial,
/// Subscription is paused.
Paused,
/// Subscription is unpaid.
Unpaid,
/// Subscription is a one-time payment.
Onetime,
/// Subscription is cancelled.
Cancelled,
/// Subscription has failed.
Failed,
}

View File

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use crate::enums::PayoutStatus;
use crate::enums::{
AttemptStatus, Country, CountryAlpha2, CountryAlpha3, DisputeStatus, EventType, IntentStatus,
MandateStatus, PaymentMethod, PaymentMethodType, RefundStatus,
MandateStatus, PaymentMethod, PaymentMethodType, RefundStatus, SubscriptionStatus,
};
impl Display for NumericCountryCodeParseError {
@ -2214,6 +2214,15 @@ impl From<MandateStatus> for Option<EventType> {
}
}
impl From<SubscriptionStatus> for Option<EventType> {
fn from(value: SubscriptionStatus) -> Self {
match value {
SubscriptionStatus::Active => Some(EventType::InvoicePaid),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]