Files
tomtomgames-app/public_html/api/payout_process.php
T

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']);