fix(stripe): ignore missing subscriptions in webhook jobs

Avoid failing Stripe webhook processing when local subscriptions are missing, and cover ignored invoice/payment/subscription events with feature tests.
This commit is contained in:
Andras Bacsai
2026-05-11 16:56:00 +02:00
parent c33364db71
commit ff149b8daa
2 changed files with 74 additions and 7 deletions
+8 -7
View File
@@ -9,6 +9,7 @@ use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Str;
use Stripe\StripeClient;
class StripeProcessJob implements ShouldBeEncrypted, ShouldQueue
{
@@ -35,7 +36,7 @@ class StripeProcessJob implements ShouldBeEncrypted, ShouldQueue
$data = data_get($this->event, 'data.object');
switch ($type) {
case 'radar.early_fraud_warning.created':
$stripe = new \Stripe\StripeClient(config('subscription.stripe_api_key'));
$stripe = new StripeClient(config('subscription.stripe_api_key'));
$id = data_get($data, 'id');
$charge = data_get($data, 'charge');
if ($charge) {
@@ -94,12 +95,12 @@ class StripeProcessJob implements ShouldBeEncrypted, ShouldQueue
}
$subscription = Subscription::where('stripe_customer_id', $customerId)->first();
if (! $subscription) {
throw new \RuntimeException("No subscription found for customer: {$customerId}");
break;
}
if ($subscription->stripe_subscription_id) {
try {
$stripe = new \Stripe\StripeClient(config('subscription.stripe_api_key'));
$stripe = new StripeClient(config('subscription.stripe_api_key'));
$stripeSubscription = $stripe->subscriptions->retrieve(
$subscription->stripe_subscription_id
);
@@ -154,7 +155,7 @@ class StripeProcessJob implements ShouldBeEncrypted, ShouldQueue
$subscription = Subscription::where('stripe_customer_id', $customerId)->first();
if (! $subscription) {
// send_internal_notification('invoice.payment_failed failed but no subscription found in Coolify for customer: '.$customerId);
throw new \RuntimeException("No subscription found for customer: {$customerId}");
break;
}
$team = data_get($subscription, 'team');
if (! $team) {
@@ -165,7 +166,7 @@ class StripeProcessJob implements ShouldBeEncrypted, ShouldQueue
// Verify payment status with Stripe API before sending failure notification
if ($paymentIntentId) {
try {
$stripe = new \Stripe\StripeClient(config('subscription.stripe_api_key'));
$stripe = new StripeClient(config('subscription.stripe_api_key'));
$paymentIntent = $stripe->paymentIntents->retrieve($paymentIntentId);
if (in_array($paymentIntent->status, ['processing', 'succeeded', 'requires_action', 'requires_confirmation'])) {
@@ -190,7 +191,7 @@ class StripeProcessJob implements ShouldBeEncrypted, ShouldQueue
$subscription = Subscription::where('stripe_customer_id', $customerId)->first();
if (! $subscription) {
// send_internal_notification('payment_intent.payment_failed, no subscription found in Coolify for customer: '.$customerId);
throw new \RuntimeException("No subscription found in Coolify for customer: {$customerId}");
break;
}
if ($subscription->stripe_invoice_paid) {
// send_internal_notification('payment_intent.payment_failed but invoice is active for customer: '.$customerId);
@@ -334,7 +335,7 @@ class StripeProcessJob implements ShouldBeEncrypted, ShouldQueue
}
} else {
// send_internal_notification('Subscription deleted but no subscription found in Coolify for customer: '.$customerId);
throw new \RuntimeException("No subscription found in Coolify for customer: {$customerId}");
break;
}
break;
default: