['card'], 'line_items' => [ [ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => "Invoice {$invoice->invoice_number}", ], 'unit_amount' => (int) ($invoice->balance_due * 100), ], 'quantity' => 1, ], ], 'mode' => 'payment', 'success_url' => route('stripe.success', $invoice), 'cancel_url' => route('invoices.show', $invoice), 'metadata' => [ 'invoice_id' => $invoice->id, ], ]); return redirect($session->url); } public function webhook(Request $request) { \Log::info('Stripe webhook received'); $payload = $request->getContent(); $signature = $request->header('Stripe-Signature'); try { $event = \Stripe\Webhook::constructEvent( $payload, $signature, config('services.stripe.webhook_secret') ); } catch (\Exception $e) { \Log::error('Stripe webhook signature verification failed', ['error' => $e->getMessage()]); return response('Invalid signature', 400); } \Log::info('Stripe webhook event', ['type' => $event->type]); if ($event->type === 'checkout.session.completed') { $session = $event->data->object; \Log::info('Processing checkout.session.completed', [ 'invoice_id' => $session->metadata->invoice_id ?? 'not set', 'payment_intent' => $session->payment_intent, ]); $invoice = Invoice::find($session->metadata->invoice_id); if ($invoice) { Stripe::setApiKey(config('services.stripe.secret')); // Retrieve PaymentIntent with expanded charge and balance_transaction $paymentIntent = \Stripe\PaymentIntent::retrieve([ 'id' => $session->payment_intent, 'expand' => ['latest_charge.balance_transaction'], ]); $feeAmount = $paymentIntent->latest_charge?->balance_transaction?->fee ?? 0; $payment = Payment::create([ 'invoice_id' => $invoice->id, 'payment_date' => now(), 'status' => PaymentStatus::COMPLETED, 'payment_method' => PaymentMethod::CARD, 'reference' => $session->payment_intent, 'stripe_payment_intent_id' => $session->payment_intent, 'amount' => $session->amount_total / 100, 'fee_amount' => $feeAmount / 100, ]); \Log::info('Payment created', ['payment_id' => $payment->id, 'fee_amount' => $feeAmount]); } else { \Log::warning('Invoice not found for Stripe webhook', ['invoice_id' => $session->metadata->invoice_id]); } } return response('OK', 200); } public function checkoutTutorial() { Stripe::setApiKey(config('stripe.sk')); $session = \Stripe\Checkout\Session::create([ 'line_items' => [ [ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => 'send me money', ], 'unit_amount' => 3250, // in cents ], 'quantity' => 1, ], ], 'mode' => 'payment', 'success_url' => route('stripe.success'), 'cancel_url' => route('stripe.index'), ]); return redirect()->away($session->url); } public function success(Invoice $invoice) { return view('stripe.success', compact('invoice')); } }