src/Services/StripePaymentService.php line 273
<?phpnamespace App\Services;use Stripe\Stripe;use Stripe\PaymentIntent;use Stripe\Customer;use Stripe\Webhook;use Stripe\Exception\SignatureVerificationException;use Psr\Log\LoggerInterface;use Symfony\Component\HttpFoundation\Request;use Stripe\Checkout\Session as StripeSession;class StripePaymentService{private LoggerInterface $logger;private string $stripeSecretKey;private string $webhookSecret;public function __construct(LoggerInterface $logger,string $stripeSecretKey,string $webhookSecret) {$this->logger = $logger;$this->stripeSecretKey = $stripeSecretKey;$this->webhookSecret = $webhookSecret;Stripe::setApiKey($this->stripeSecretKey);}/*** Create a payment intent*/public function createPaymentIntent(int $amount,string $currency = 'usd',?string $customerId = null,array $metadata = []): PaymentIntent {try {$params = ['amount' => $amount, // Amount in cents'currency' => $currency,'automatic_payment_methods' => ['enabled' => true,],'metadata' => $metadata,];if ($customerId) {$params['customer'] = $customerId;}$paymentIntent = PaymentIntent::create($params);$this->logger->info('Payment intent created', ['payment_intent_id' => $paymentIntent->id,'amount' => $amount,'currency' => $currency,'customer_id' => $customerId]);return $paymentIntent;} catch (\Exception $e) {$this->logger->error('Failed to create payment intent', ['error' => $e->getMessage(),'amount' => $amount,'currency' => $currency]);throw $e;}}/*** Confirm a payment intent*/public function confirmPaymentIntent(string $paymentIntentId, string $paymentMethodId): PaymentIntent{try {$paymentIntent = PaymentIntent::retrieve($paymentIntentId);$paymentIntent = $paymentIntent->confirm(['payment_method' => $paymentMethodId,]);$this->logger->info('Payment intent confirmed', ['payment_intent_id' => $paymentIntentId,'status' => $paymentIntent->status]);return $paymentIntent;} catch (\Exception $e) {$this->logger->error('Failed to confirm payment intent', ['payment_intent_id' => $paymentIntentId,'error' => $e->getMessage()]);throw $e;}}/*** Create or retrieve a Stripe customer*/public function createCustomer(string $email, string $name = '', array $metadata = []): Customer{try {$customer = Customer::create(['email' => $email,'name' => $name,'metadata' => $metadata,]);$this->logger->info('Customer created', ['customer_id' => $customer->id,'email' => $email]);return $customer;} catch (\Exception $e) {$this->logger->error('Failed to create customer', ['email' => $email,'error' => $e->getMessage()]);throw $e;}}/*** Retrieve a payment intent*/public function getPaymentIntent(string $paymentIntentId): PaymentIntent{try {return PaymentIntent::retrieve($paymentIntentId);} catch (\Exception $e) {$this->logger->error('Failed to retrieve payment intent', ['payment_intent_id' => $paymentIntentId,'error' => $e->getMessage()]);throw $e;}}/*** Cancel a payment intent*/public function cancelPaymentIntent(string $paymentIntentId): PaymentIntent{try {$paymentIntent = PaymentIntent::retrieve($paymentIntentId);$paymentIntent = $paymentIntent->cancel();$this->logger->info('Payment intent cancelled', ['payment_intent_id' => $paymentIntentId]);return $paymentIntent;} catch (\Exception $e) {$this->logger->error('Failed to cancel payment intent', ['payment_intent_id' => $paymentIntentId,'error' => $e->getMessage()]);throw $e;}}/*** Handle Stripe webhooks*/public function handleWebhook(Request $request): array{$payload = $request->getContent();$sigHeader = $request->headers->get('stripe-signature');try {$event = Webhook::constructEvent($payload, $sigHeader, $this->webhookSecret);} catch (\UnexpectedValueException $e) {$this->logger->error('Invalid webhook payload', ['error' => $e->getMessage()]);throw $e;} catch (SignatureVerificationException $e) {$this->logger->error('Invalid webhook signature', ['error' => $e->getMessage()]);throw $e;}$this->logger->info('Webhook received', ['event_type' => $event['type'],'event_id' => $event['id']]);// Handle the eventswitch ($event['type']) {case 'payment_intent.succeeded':$this->handlePaymentSucceeded($event['data']['object']);break;case 'payment_intent.payment_failed':$this->handlePaymentFailed($event['data']['object']);break;case 'payment_intent.canceled':$this->handlePaymentCanceled($event['data']['object']);break;default:$this->logger->info('Unhandled webhook event type', ['event_type' => $event['type']]);}return ['event_type' => $event['type'],'event_id' => $event['id'],'processed' => true];}/*** Handle successful payment*/private function handlePaymentSucceeded($paymentIntent): void{$this->logger->info('Payment succeeded', ['payment_intent_id' => $paymentIntent['id'],'amount' => $paymentIntent['amount'],'currency' => $paymentIntent['currency']]);// Add your business logic here// For example: update order status, send confirmation email, etc.}/*** Handle failed payment*/private function handlePaymentFailed($paymentIntent): void{$this->logger->warning('Payment failed', ['payment_intent_id' => $paymentIntent['id'],'amount' => $paymentIntent['amount'],'currency' => $paymentIntent['currency'],'last_payment_error' => $paymentIntent['last_payment_error'] ?? null]);// Add your business logic here// For example: notify user, update order status, etc.}/*** Handle canceled payment*/private function handlePaymentCanceled($paymentIntent): void{$this->logger->info('Payment canceled', ['payment_intent_id' => $paymentIntent['id'],'amount' => $paymentIntent['amount'],'currency' => $paymentIntent['currency']]);// Add your business logic here}/*** Convert amount to cents (Stripe expects amounts in cents)*/public function convertToCents(float $amount): int{return (int) round($amount * 100);}/*** Convert amount from cents to dollars*/public function convertFromCents(int $amount): float{return $amount / 100;}public function createCheckoutSession(int $amount,string $currency = 'usd',string $successUrl,string $cancelUrl,array $metadata = []): array {try {$session = StripeSession::create(['payment_method_types' => ['card'],'line_items' => [['price_data' => ['currency' => $currency,'product_data' => ['name' => 'Paiement',],'unit_amount' => $amount,],'quantity' => 1,]],'mode' => 'payment','success_url' => $successUrl,'cancel_url' => $cancelUrl,'metadata' => $metadata,]);$this->logger->info('Checkout session créée', ['session_id' => $session->id,'url' => $session->url,]);return [ 'url' => $session->url,'session_id' => $session->id,];} catch (\Exception $e) {$this->logger->error('Erreur création session checkout', ['error' => $e->getMessage(),]);throw $e;}}}