diff --git a/api/webhook.php b/api/webhook.php index 2bd72c4..15b02e5 100644 --- a/api/webhook.php +++ b/api/webhook.php @@ -9,7 +9,7 @@ require_once __DIR__ . '/../includes/stripe.php'; header('Content-Type: application/json'); -$payload = file_get_contents('php://input'); +$payload = file_get_contents('php://input'); $sigHeader = $_SERVER['HTTP_STRIPE_SIGNATURE'] ?? ''; // Verify webhook signature (if secret is configured) @@ -31,31 +31,51 @@ if (!empty(STRIPE_WEBHOOK_SECRET) && STRIPE_WEBHOOK_SECRET !== 'whsec_your_webho } $eventType = $event['type'] ?? ''; -$data = $event['data']['object'] ?? []; +$data = $event['data']['object'] ?? []; switch ($eventType) { - case 'payment_intent.succeeded': - $paymentIntentId = $data['id'] ?? ''; - $orderId = $data['metadata']['order_id'] ?? ''; - - if ($orderId) { + + case 'checkout.session.completed': + // Stripe Checkout (hosted page) — metadata is on the session + $orderId = $data['metadata']['order_id'] ?? ''; + $paymentIntentId = $data['payment_intent'] ?? ''; + if ($orderId && ($data['payment_status'] ?? '') === 'paid') { db()->update('orders', [ - 'payment_status' => 'paid', - 'order_status' => 'confirmed' + 'payment_status' => 'paid', + 'order_status' => 'confirmed', + 'stripe_payment_intent' => $paymentIntentId, ], 'order_id = :id', ['id' => $orderId] ); - - // Send confirmation email $order = db()->fetch("SELECT * FROM orders WHERE order_id = :id", ['id' => $orderId]); if ($order) { sendOrderConfirmationEmail($order); } } break; - + + case 'payment_intent.succeeded': + // Payment Intent flow (embedded checkout) — metadata.order_id set directly on PI + $paymentIntentId = $data['id'] ?? ''; + $orderId = $data['metadata']['order_id'] ?? ''; + if ($orderId) { + db()->update('orders', + [ + 'payment_status' => 'paid', + 'order_status' => 'confirmed', + ], + 'order_id = :id', + ['id' => $orderId] + ); + $order = db()->fetch("SELECT * FROM orders WHERE order_id = :id", ['id' => $orderId]); + if ($order) { + sendOrderConfirmationEmail($order); + } + } + break; + case 'payment_intent.payment_failed': $orderId = $data['metadata']['order_id'] ?? ''; if ($orderId) { @@ -66,14 +86,14 @@ switch ($eventType) { ); } break; - + case 'charge.refunded': $paymentIntentId = $data['payment_intent'] ?? ''; if ($paymentIntentId) { db()->update('orders', [ 'payment_status' => 'refunded', - 'order_status' => 'refunded' + 'order_status' => 'refunded', ], 'stripe_payment_intent = :pi', ['pi' => $paymentIntentId] @@ -89,9 +109,9 @@ echo json_encode(['received' => true]); * Send order confirmation email */ function sendOrderConfirmationEmail($order) { - $items = json_decode($order['items'], true) ?? []; + $items = json_decode($order['items'], true) ?? []; $shippingAddress = json_decode($order['shipping_address'], true) ?? []; - + $itemsHtml = ''; foreach ($items as $item) { $itemsHtml .= sprintf( @@ -101,22 +121,22 @@ function sendOrderConfirmationEmail($order) { $item['total'] ); } - + $html = <<
Thank you for your order, {$order['customer_name']}!
- +Order #: {$order['order_number']}
Total: \${$order['total']}
| \${$order['total']} |
{$shippingAddress['address']}
{$shippingAddress['city']}, {$shippingAddress['state']} {$shippingAddress['zip']}
We'll send you tracking information once your order ships.
Tom's Java Jive | Premium Coffee