54 lines
1.9 KiB
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]);
|
|
}
|
|
}
|