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
@@ -2,10 +2,14 @@
use App\Jobs\ServerLimitCheckJob;
use App\Jobs\StripeProcessJob;
use App\Jobs\SubscriptionInvoiceFailedJob;
use App\Jobs\VerifyStripeSubscriptionStatusJob;
use App\Models\Subscription;
use App\Models\Team;
use App\Models\User;
use App\Notifications\Internal\GeneralNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Queue;
uses(RefreshDatabase::class);
@@ -228,3 +232,65 @@ describe('ServerLimitCheckJob dispatch is guarded by team check', function () {
Queue::assertNotPushed(ServerLimitCheckJob::class);
});
});
describe('missing subscription Stripe webhooks are ignored', function () {
test('does not send internal notifications or queue follow-up jobs', function (array $event) {
Queue::fake();
$rootTeam = Team::factory()->create(['id' => 0]);
$rootTeam->discordNotificationSettings()->update(['discord_enabled' => true]);
Notification::fake();
$job = new StripeProcessJob($event);
$job->handle();
Notification::assertNothingSent();
Notification::assertNotSentTo($rootTeam, GeneralNotification::class);
Queue::assertNotPushed(SubscriptionInvoiceFailedJob::class);
Queue::assertNotPushed(VerifyStripeSubscriptionStatusJob::class);
})->with([
'invoice paid' => [[
'type' => 'invoice.paid',
'data' => [
'object' => [
'customer' => 'cus_missing_invoice_paid',
'amount_paid' => 1000,
'subscription' => 'sub_missing_invoice_paid',
'lines' => [
'data' => [[
'plan' => ['id' => 'price_dynamic_monthly'],
]],
],
],
],
]],
'invoice payment failed' => [[
'type' => 'invoice.payment_failed',
'data' => [
'object' => [
'customer' => 'cus_missing_invoice_payment_failed',
'id' => 'in_missing_invoice_payment_failed',
'payment_intent' => null,
],
],
]],
'payment intent payment failed' => [[
'type' => 'payment_intent.payment_failed',
'data' => [
'object' => [
'customer' => 'cus_missing_payment_intent_failed',
],
],
]],
'customer subscription deleted' => [[
'type' => 'customer.subscription.deleted',
'data' => [
'object' => [
'customer' => 'cus_missing_subscription_deleted',
'id' => 'sub_missing_subscription_deleted',
],
],
]],
]);
});