false, 'ERROR' => 'missing_TabID']); if ($userID === 0) apiAbort(['OK' => false, 'ERROR' => 'missing_UserID']); if ($newAuthAmount <= 0) apiAbort(['OK' => false, 'ERROR' => 'missing_NewAuthAmount']); $qTab = queryOne(" SELECT t.ID, t.OwnerUserID, t.StatusID, t.AuthAmountCents, t.StripePaymentIntentID, b.TabMaxAuthAmount FROM Tabs t JOIN Businesses b ON b.ID = t.BusinessID WHERE t.ID = ? LIMIT 1 ", [$tabID]); if (!$qTab) apiAbort(['OK' => false, 'ERROR' => 'tab_not_found']); if ((int) $qTab['StatusID'] !== 1) apiAbort(['OK' => false, 'ERROR' => 'tab_not_open']); if ((int) $qTab['OwnerUserID'] !== $userID) apiAbort(['OK' => false, 'ERROR' => 'not_owner']); $newAuthCents = round($newAuthAmount * 100); $maxCents = round((float) ($qTab['TabMaxAuthAmount'] ?? 0) * 100); if ($newAuthCents <= (int) $qTab['AuthAmountCents']) apiAbort(['OK' => false, 'ERROR' => 'not_an_increase', 'MESSAGE' => 'New amount must be higher than current authorization.']); if ($maxCents > 0 && $newAuthCents > $maxCents) apiAbort(['OK' => false, 'ERROR' => 'exceeds_max', 'MESSAGE' => "Maximum authorization is \$" . number_format((float) $qTab['TabMaxAuthAmount'], 2) . "."]); // Update Stripe PI amount $updateData = stripeRequest('POST', "https://api.stripe.com/v1/payment_intents/{$qTab['StripePaymentIntentID']}", [ 'amount' => $newAuthCents, ]); if (isset($updateData['id']) && (int) ($updateData['amount'] ?? 0) === $newAuthCents) { queryTimed("UPDATE Tabs SET AuthAmountCents = ? WHERE ID = ?", [$newAuthCents, $tabID]); jsonResponse([ 'OK' => true, 'AUTH_AMOUNT_CENTS' => $newAuthCents, 'PREVIOUS_AUTH_CENTS' => (int) $qTab['AuthAmountCents'], ]); } else { $errMsg = $updateData['error']['message'] ?? 'Authorization increase declined'; apiAbort(['OK' => false, 'ERROR' => 'increase_declined', 'MESSAGE' => $errMsg, 'CURRENT_AUTH_CENTS' => (int) $qTab['AuthAmountCents']]); } } catch (Exception $e) { jsonResponse(['OK' => false, 'ERROR' => 'server_error', 'MESSAGE' => $e->getMessage()]); }