58 lines
2.0 KiB
PHP
58 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Stripe;
|
|
|
|
use App\Data\Payment\VerifiedCheckoutResponseDTO;
|
|
use App\Models\User;
|
|
use Exception;
|
|
use Log;
|
|
use Stripe\Exception\ApiErrorException;
|
|
use Stripe\StripeClient;
|
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
|
|
|
final readonly class VerifyStripeSessionAction
|
|
{
|
|
public function __construct(private StripeClient $stripe) {}
|
|
|
|
/**
|
|
* Execute the action.
|
|
*/
|
|
public function execute(int $orderId, string $stripeSessionId, User $user): VerifiedCheckoutResponseDTO
|
|
{
|
|
/**
|
|
* Check if the order is actually made by user
|
|
*/
|
|
$order = $user->orders()
|
|
->whereId($orderId)
|
|
->first();
|
|
if (! $order) {
|
|
throw new AccessDeniedHttpException('Order is not made by you');
|
|
}
|
|
if (! $order->stripeSession()->where('session_id', $stripeSessionId)->exists()) {
|
|
throw new AccessDeniedHttpException('Stripe session is not made by you');
|
|
}
|
|
|
|
try {
|
|
$session = $this->stripe->checkout->sessions->retrieve($stripeSessionId);
|
|
} catch (ApiErrorException $e) {
|
|
Log::error('Stripe api is not available: ', [$e->getMessage()]);
|
|
throw new ServiceUnavailableHttpException('Stripe api is not available');
|
|
} catch (Exception $e) {
|
|
throw new NotFoundHttpException('Invalid Stripe session id');
|
|
}
|
|
|
|
if ($session->payment_status !== 'paid' || $session->status !== 'complete') {
|
|
return VerifiedCheckoutResponseDTO::failure('Payment Unsuccessful');
|
|
}
|
|
|
|
return VerifiedCheckoutResponseDTO::success(
|
|
message: 'Payment Successful',
|
|
amount: $session->amount_total,
|
|
transactionId: $session->payment_intent,
|
|
mode: $session->payment_method_types[0],
|
|
);
|
|
}
|
|
}
|