Merge remote-tracking branch 'origin/next' into feat/railpack
This commit is contained in:
commit
0f904d792b
3 changed files with 74 additions and 11 deletions
|
|
@ -9,6 +9,7 @@
|
|||
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 @@ public function handle(): void
|
|||
$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 @@ public function handle(): void
|
|||
}
|
||||
$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 @@ public function handle(): void
|
|||
$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 @@ public function handle(): void
|
|||
// 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 @@ public function handle(): void
|
|||
$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 @@ public function handle(): void
|
|||
}
|
||||
} 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:
|
||||
|
|
|
|||
|
|
@ -47,14 +47,10 @@ public function submit()
|
|||
try {
|
||||
$this->rateLimit(10);
|
||||
$this->validate();
|
||||
$firstLogin = auth()->user()->created_at == auth()->user()->updated_at;
|
||||
auth()->user()->fill([
|
||||
'password' => Hash::make($this->password),
|
||||
'force_password_reset' => false,
|
||||
])->save();
|
||||
if ($firstLogin) {
|
||||
send_internal_notification('First login for '.auth()->user()->email);
|
||||
}
|
||||
|
||||
return redirect()->route('dashboard');
|
||||
} catch (\Throwable $e) {
|
||||
|
|
|
|||
|
|
@ -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 @@
|
|||
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',
|
||||
],
|
||||
],
|
||||
]],
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue