refactor(billing): Enhance Stripe subscription status handling and notifications

This commit is contained in:
Andras Bacsai
2025-03-01 12:43:21 +01:00
parent 07cbec7ddc
commit 1909865a33

View File

@@ -73,19 +73,21 @@ class StripeProcessJob implements ShouldQueue
} }
$subscription = Subscription::where('team_id', $teamId)->first(); $subscription = Subscription::where('team_id', $teamId)->first();
if ($subscription) { if ($subscription) {
send_internal_notification('Old subscription activated for team: '.$teamId); // send_internal_notification('Old subscription activated for team: '.$teamId);
$subscription->update([ $subscription->update([
'stripe_subscription_id' => $subscriptionId, 'stripe_subscription_id' => $subscriptionId,
'stripe_customer_id' => $customerId, 'stripe_customer_id' => $customerId,
'stripe_invoice_paid' => true, 'stripe_invoice_paid' => true,
'stripe_past_due' => false,
]); ]);
} else { } else {
send_internal_notification('New subscription for team: '.$teamId); // send_internal_notification('New subscription for team: '.$teamId);
Subscription::create([ Subscription::create([
'team_id' => $teamId, 'team_id' => $teamId,
'stripe_subscription_id' => $subscriptionId, 'stripe_subscription_id' => $subscriptionId,
'stripe_customer_id' => $customerId, 'stripe_customer_id' => $customerId,
'stripe_invoice_paid' => true, 'stripe_invoice_paid' => true,
'stripe_past_due' => false,
]); ]);
} }
break; break;
@@ -100,6 +102,7 @@ class StripeProcessJob implements ShouldQueue
if ($subscription) { if ($subscription) {
$subscription->update([ $subscription->update([
'stripe_invoice_paid' => true, 'stripe_invoice_paid' => true,
'stripe_past_due' => false,
]); ]);
} else { } else {
throw new \RuntimeException("No subscription found for customer: {$customerId}"); throw new \RuntimeException("No subscription found for customer: {$customerId}");
@@ -119,9 +122,7 @@ class StripeProcessJob implements ShouldQueue
} }
if (! $subscription->stripe_invoice_paid) { if (! $subscription->stripe_invoice_paid) {
SubscriptionInvoiceFailedJob::dispatch($team); SubscriptionInvoiceFailedJob::dispatch($team);
send_internal_notification('Invoice payment failed: '.$customerId); // send_internal_notification('Invoice payment failed: '.$customerId);
} else {
send_internal_notification('Invoice payment failed but already paid: '.$customerId);
} }
break; break;
case 'payment_intent.payment_failed': case 'payment_intent.payment_failed':
@@ -136,7 +137,7 @@ class StripeProcessJob implements ShouldQueue
return; return;
} }
send_internal_notification('Subscription payment failed for customer: '.$customerId); // send_internal_notification('Subscription payment failed for customer: '.$customerId);
break; break;
case 'customer.subscription.created': case 'customer.subscription.created':
$customerId = data_get($data, 'customer'); $customerId = data_get($data, 'customer');
@@ -158,7 +159,7 @@ class StripeProcessJob implements ShouldQueue
} }
$subscription = Subscription::where('team_id', $teamId)->first(); $subscription = Subscription::where('team_id', $teamId)->first();
if ($subscription) { if ($subscription) {
send_internal_notification("Subscription already exists for team: {$teamId}"); // send_internal_notification("Subscription already exists for team: {$teamId}");
throw new \RuntimeException("Subscription already exists for team: {$teamId}"); throw new \RuntimeException("Subscription already exists for team: {$teamId}");
} else { } else {
Subscription::create([ Subscription::create([
@@ -182,7 +183,7 @@ class StripeProcessJob implements ShouldQueue
$subscription = Subscription::where('stripe_customer_id', $customerId)->first(); $subscription = Subscription::where('stripe_customer_id', $customerId)->first();
if (! $subscription) { if (! $subscription) {
if ($status === 'incomplete_expired') { if ($status === 'incomplete_expired') {
send_internal_notification('Subscription incomplete expired'); // send_internal_notification('Subscription incomplete expired');
throw new \RuntimeException('Subscription incomplete expired'); throw new \RuntimeException('Subscription incomplete expired');
} }
if ($teamId) { if ($teamId) {
@@ -217,16 +218,40 @@ class StripeProcessJob implements ShouldQueue
'stripe_plan_id' => $planId, 'stripe_plan_id' => $planId,
'stripe_cancel_at_period_end' => $cancelAtPeriodEnd, 'stripe_cancel_at_period_end' => $cancelAtPeriodEnd,
]); ]);
if ($status === 'paused' || $status === 'incomplete_expired' || $status === 'past_due') { if ($status === 'paused' || $status === 'incomplete_expired') {
if ($subscription->stripe_subscription_id === $subscriptionId) { if ($subscription->stripe_subscription_id === $subscriptionId) {
$subscription->update([ $subscription->update([
'stripe_invoice_paid' => false, 'stripe_invoice_paid' => false,
]); ]);
} }
} }
if ($status === 'past_due') {
if ($subscription->stripe_subscription_id === $subscriptionId) {
$subscription->update([
'stripe_past_due' => true,
]);
send_internal_notification('Past Due: '.$customerId.'Subscription ID: '.$subscriptionId);
}
}
if ($status === 'unpaid') {
if ($subscription->stripe_subscription_id === $subscriptionId) {
$subscription->update([
'stripe_invoice_paid' => false,
]);
send_internal_notification('Unpaid: '.$customerId.'Subscription ID: '.$subscriptionId);
}
$team = data_get($subscription, 'team');
if ($team) {
$team->subscriptionEnded();
} else {
send_internal_notification('Subscription unpaid but no team found in Coolify for customer: '.$customerId);
throw new \RuntimeException("No team found in Coolify for customer: {$customerId}");
}
}
if ($status === 'active') { if ($status === 'active') {
if ($subscription->stripe_subscription_id === $subscriptionId) { if ($subscription->stripe_subscription_id === $subscriptionId) {
$subscription->update([ $subscription->update([
'stripe_past_due' => false,
'stripe_invoice_paid' => true, 'stripe_invoice_paid' => true,
]); ]);
} }