mirror of
https://github.com/myronblair/tomtomgames-app
synced 2026-06-30 17:49:57 -05:00
154 lines
6.6 KiB
PHP
154 lines
6.6 KiB
PHP
<?php
|
|
ob_start();
|
|
require_once __DIR__ . '/../../includes/auth.php';
|
|
require_once __DIR__ . '/../../includes/square.php';
|
|
ob_end_clean();
|
|
header('Content-Type: application/json');
|
|
|
|
if (!isLoggedIn() || empty($_SESSION['is_admin'])) {
|
|
echo json_encode(['success'=>false,'error'=>'Forbidden']); exit;
|
|
}
|
|
|
|
$adminId = (int)$_SESSION['user_id'];
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$action = $_GET['action'] ?? 'list_settings';
|
|
|
|
// ── GET actions ──────────────────────────────────────────
|
|
if ($method === 'GET') {
|
|
if ($action === 'list_settings') {
|
|
$rows = db()->query("SELECT * FROM admin_payout_settings ORDER BY sort_order ASC, id ASC")->fetchAll();
|
|
echo json_encode(['success'=>true, 'settings'=>$rows]);
|
|
exit;
|
|
}
|
|
if ($action === 'cashout_detail') {
|
|
$id = (int)($_GET['id'] ?? 0);
|
|
$stmt = db()->prepare("
|
|
SELECT cr.*, u.username, u.alias AS user_alias, u.email,
|
|
pm.method_type AS saved_payout_type, pm.account_handle AS saved_payout_handle, pm.label AS saved_payout_label
|
|
FROM cashout_requests cr
|
|
JOIN users u ON cr.user_id = u.id
|
|
LEFT JOIN payout_methods pm ON pm.user_id = cr.user_id AND pm.is_default = 1
|
|
WHERE cr.id = ?
|
|
");
|
|
$stmt->execute([$id]);
|
|
$row = $stmt->fetch();
|
|
echo json_encode(['success'=>true, 'cashout'=>$row]);
|
|
exit;
|
|
}
|
|
echo json_encode(['success'=>false,'error'=>'Unknown action']); exit;
|
|
}
|
|
|
|
if ($method !== 'POST') { echo json_encode(['success'=>false,'error'=>'Method not allowed']); exit; }
|
|
$d = json_decode(file_get_contents('php://input'), true);
|
|
|
|
// ── Update payout settings ────────────────────────────────
|
|
if ($action === 'update_setting') {
|
|
$id = (int)($d['id'] ?? 0);
|
|
$handle = substr(trim($d['handle']??''), 0, 200);
|
|
$instr = substr(trim($d['instructions']??''), 0, 500);
|
|
$enabled = (int)(bool)($d['is_enabled']??1);
|
|
$label = substr(trim($d['label']??''), 0, 100);
|
|
$sort = (int)($d['sort_order']??0);
|
|
db()->prepare("UPDATE admin_payout_settings SET label=?,handle=?,instructions=?,is_enabled=?,sort_order=? WHERE id=?")
|
|
->execute([$label,$handle,$instr,$enabled,$sort,$id]);
|
|
echo json_encode(['success'=>true]); exit;
|
|
}
|
|
|
|
// ── Process cashout payout ────────────────────────────────
|
|
if ($action === 'process_payout') {
|
|
$cashoutId = (int)($d['cashout_id'] ?? 0);
|
|
$payoutKey = trim($d['payout_method_key'] ?? '');
|
|
$payoutType = trim($d['payout_type'] ?? 'manual'); // 'manual' or 'square_gift_card'
|
|
$note = substr(trim($d['note'] ?? ''), 0, 500);
|
|
|
|
// Load cashout
|
|
$stmt = db()->prepare("SELECT cr.*, u.username, u.alias, u.email FROM cashout_requests cr JOIN users u ON cr.user_id=u.id WHERE cr.id=? AND cr.status IN ('pending','locked')");
|
|
$stmt->execute([$cashoutId]);
|
|
$cashout = $stmt->fetch();
|
|
if (!$cashout) { echo json_encode(['success'=>false,'error'=>'Cashout not found or already processed']); exit; }
|
|
|
|
// Amount in cents (1 token = $1)
|
|
$amountCents = (int)round($cashout['tokens'] * 100);
|
|
|
|
// Load payout setting
|
|
$pset = db()->prepare("SELECT * FROM admin_payout_settings WHERE method_key=? AND is_enabled=1");
|
|
$pset->execute([$payoutKey]);
|
|
$setting = $pset->fetch();
|
|
|
|
$squareTxnId = null;
|
|
$giftCardGan = null;
|
|
$giftCardBal = null;
|
|
$txnStatus = 'completed';
|
|
|
|
if ($payoutType === 'square_gift_card') {
|
|
// ── Square Gift Card Flow ─────────────────────────
|
|
try {
|
|
// 1. Create gift card
|
|
$gcRes = SquareClient::post('/v2/gift-cards', [
|
|
'idempotency_key' => 'gc-create-' . $cashoutId . '-' . time(),
|
|
'location_id' => SQUARE_LOCATION_ID,
|
|
'gift_card' => ['type' => 'DIGITAL'],
|
|
]);
|
|
|
|
if (empty($gcRes['gift_card']['id'])) {
|
|
throw new Exception('Failed to create gift card: ' . json_encode($gcRes));
|
|
}
|
|
|
|
$gcId = $gcRes['gift_card']['id'];
|
|
$gcGan = $gcRes['gift_card']['gan'] ?? '';
|
|
|
|
// 2. Activate gift card with balance
|
|
$actRes = SquareClient::post('/v2/gift-card-activities', [
|
|
'idempotency_key' => 'gc-activate-' . $cashoutId . '-' . time(),
|
|
'gift_card_activity' => [
|
|
'type' => 'ACTIVATE',
|
|
'location_id' => SQUARE_LOCATION_ID,
|
|
'gift_card_id' => $gcId,
|
|
'activate_activity_details' => [
|
|
'amount_money' => [
|
|
'amount' => $amountCents,
|
|
'currency' => 'USD',
|
|
],
|
|
],
|
|
],
|
|
]);
|
|
|
|
if (empty($actRes['gift_card_activity']['id'])) {
|
|
throw new Exception('Failed to activate gift card: ' . json_encode($actRes));
|
|
}
|
|
|
|
$giftCardGan = $gcGan;
|
|
$giftCardBal = $amountCents;
|
|
$squareTxnId = $actRes['gift_card_activity']['id'];
|
|
|
|
} catch (Exception $e) {
|
|
echo json_encode(['success'=>false,'error'=>'Square error: ' . $e->getMessage()]); exit;
|
|
}
|
|
}
|
|
|
|
// ── Mark cashout as sent ──────────────────────────────
|
|
db()->beginTransaction();
|
|
try {
|
|
db()->prepare("UPDATE cashout_requests SET status='sent', admin_note=?, resolved_at=NOW() WHERE id=?")
|
|
->execute([$note, $cashoutId]);
|
|
|
|
db()->prepare("INSERT INTO cashout_transactions (cashout_id,admin_id,payout_method,payout_type,amount_cents,square_txn_id,gift_card_gan,gift_card_balance,note,status)
|
|
VALUES (?,?,?,?,?,?,?,?,?,'completed')")
|
|
->execute([$cashoutId, $adminId, $payoutKey, $payoutType, $amountCents, $squareTxnId, $giftCardGan, $giftCardBal, $note]);
|
|
|
|
db()->commit();
|
|
} catch (Exception $e) {
|
|
db()->rollBack();
|
|
echo json_encode(['success'=>false,'error'=>'DB error: '.$e->getMessage()]); exit;
|
|
}
|
|
|
|
$response = ['success'=>true, 'status'=>'sent', 'amount_cents'=>$amountCents];
|
|
if ($giftCardGan) {
|
|
$response['gift_card_gan'] = $giftCardGan;
|
|
$response['gift_card_balance'] = $giftCardBal;
|
|
}
|
|
echo json_encode($response); exit;
|
|
}
|
|
|
|
echo json_encode(['success'=>false,'error'=>'Unknown action']);
|