ekart/backend/app/Http/Controllers/StripeWebhookController.php

54 lines
1.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Actions\MarkPaymentAsPaidAction;
use App\Enums\StripeEventType;
use App\Models\Payment;
use Illuminate\Http\Request;
use Log;
use Stripe\Exception\SignatureVerificationException;
use Stripe\Webhook;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use UnexpectedValueException;
class StripeWebhookController extends Controller
{
public function __construct(private readonly MarkPaymentAsPaidAction $paidAction) {}
public function __invoke(Request $request)
{
$payload = $request->getContent();
$sigHeader = $request->header('Stripe-Signature');
try {
$event = Webhook::constructEvent($payload, $sigHeader, config('services.stripe.webhook'));
} catch (SignatureVerificationException|UnexpectedValueException $e) {
Log::error('Stripe webhook signature verification error.', [$e->getMessage()]);
throw new BadRequestHttpException('Invalid Signature');
}
if ($event->type === StripeEventType::CheckoutSessionCompleted->value) {
$sessionId = $event->data->object->id ?? null;
if ($sessionId) {
$this->handleCheckoutSessionCompleted($sessionId);
} else {
throw new NotFoundHttpException('Session id not found in event');
}
}
}
private function handleCheckoutSessionCompleted(string $sessionId): void
{
$payment = Payment::where('transaction_id', $sessionId)->first();
if (! $payment) {
Log::error('Stripe Webhook: Payment record not found.', ['session_id' => $sessionId]);
throw new NotFoundHttpException('Payment record not found');
}
$this->paidAction->execute($payment);
Log::info('Stripe Webhook: Payment successfully marked as paid', ['order_id' => $payment->order_id]);
}
}