PHP WebShell

Текущая директория: /var/www/bitcardoApp/backyard/models/giftcards

Просмотр файла: bulk_actions_post.php

<?php
// backyard/models/giftcards/bulk_actions_post.php
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
ob_start(); ini_set('display_errors','0'); error_reporting(E_ALL);

function out($data, int $code=200){ http_response_code($code); $buf=ob_get_clean(); if($buf){ $data['_diag']=substr($buf,0,500);} echo json_encode($data); exit; }

function safe_now(mysqli $conn){
  $r = mysqli_query($conn, "SELECT NOW() as n");
  $row = $r? mysqli_fetch_assoc($r):null;
  if($r) mysqli_free_result($r);
  return $row? $row['n'] : date('Y-m-d H:i:s');
}

try{
  if($_SERVER['REQUEST_METHOD']!=='POST'){ out(['success'=>false,'message'=>'Method not allowed'],405); }

  $dbPath = __DIR__ . '/../../config/db_config.php';
  if(!file_exists($dbPath)) out(['success'=>false,'message'=>'DB config missing'],500);
  include_once $dbPath;
  if(!isset($conn) || !($conn instanceof mysqli)) out(['success'=>false,'message'=>'DB connection not available'],500);

  $raw = file_get_contents('php://input');
  $payload = json_decode($raw,true);
  $action = strtolower(trim((string)($payload['action'] ?? '')));
  $refs   = $payload['refs'] ?? [];

  if(!in_array($action, ['approve','decline'], true)) out(['success'=>false,'message'=>'Bad action'],400);
  if(!is_array($refs) || empty($refs)) out(['success'=>false,'message'=>'No refs'],400);

  // sanitize and cap
  $refs = array_values(array_unique(array_filter(array_map(function($r){ return substr(trim((string)$r),0,64); }, $refs))));
  if(empty($refs)) out(['success'=>false,'message'=>'No refs'],400);
  if(count($refs)>100) $refs = array_slice($refs,0,100);

  $results = [];
  foreach($refs as $cardRef){
    $ref_safe = mysqli_real_escape_string($conn, $cardRef);

    // fetch card
    $q = "SELECT trade_id, user_id, trade_status, est_payout_ngn FROM card_trade WHERE card_ref='{$ref_safe}' LIMIT 1";
    $r = mysqli_query($conn,$q);
    $card = $r? mysqli_fetch_assoc($r):null;
    if($r) mysqli_free_result($r);

    if(!$card){
      $results[] = ['ref'=>$cardRef,'ok'=>false,'msg'=>'Not found'];
      continue;
    }

    $trade_id = (int)$card['trade_id'];
    $user_id  = (int)$card['user_id'];
    $status   = strtoupper(trim((string)$card['trade_status']));
    $payout   = (float)($card['est_payout_ngn'] ?? 0);

    mysqli_begin_transaction($conn);
    try{
      if($action==='approve'){
        if(in_array($status, ['APPROVED','SUCCESS','COMPLETED'], true)){
          // Already approved → idempotent success
          mysqli_commit($conn);
          $results[] = ['ref'=>$cardRef,'ok'=>true,'msg'=>'Already approved'];
          continue;
        }

        // 1) Update status + completed time
        $now = safe_now($conn);
        $u1 = "UPDATE card_trade SET trade_status='APPROVED', trade_completed='{$now}' WHERE trade_id={$trade_id} LIMIT 1";
        if(!mysqli_query($conn,$u1)) throw new Exception('Update status failed');

        // 2) Ensure NGN fiat wallet
        $wsql = "SELECT wallet_id, balance FROM user_wallets WHERE user_id={$user_id} AND coin='NGN' AND type='fiat' LIMIT 1";
        $wr = mysqli_query($conn,$wsql);
        $wallet = $wr? mysqli_fetch_assoc($wr):null;
        if($wr) mysqli_free_result($wr);

        if(!$wallet){
          $csql = "INSERT INTO user_wallets (cwallet_id, user_id, wallet_add, bank_name, wallet_qr, coin, icon, balance, type, label, wallet_status, created_at, updated_at)
                   VALUES (NULL, {$user_id}, NULL, NULL, NULL, 'NGN', NULL, 0.0000000000, 'fiat', 'Naira Wallet', 'Active', NOW(), NOW())";
          if(!mysqli_query($conn,$csql)) throw new Exception('Create wallet failed');
          $wallet_id = (int)mysqli_insert_id($conn);
        } else {
          $wallet_id = (int)$wallet['wallet_id'];
        }

        // 3) Credit payout
        $payout_sql = number_format($payout, 10, '.', '');
        $u2 = "UPDATE user_wallets SET balance = balance + {$payout_sql}, updated_at = NOW() WHERE wallet_id={$wallet_id} LIMIT 1";
        if(!mysqli_query($conn,$u2)) throw new Exception('Credit wallet failed');

        // 4) Log transaction
        $ins = sprintf(
          "INSERT INTO transactions (coin, user_id, wallet_id, transfer_id, sender_address, receiver_address, amount, type, txid, reference, provider, provider_meta, confirmation, status, applied, swap_id, note, updated_at, created_at)
           VALUES ('NGN', %d, '%s', NULL, 'internal', 'user_wallet', %s, 'giftcard_payout', NULL, '%s', 'system', NULL, 1, 'completed', 1, NULL, 'Gift card payout for %s', NOW(), NOW())",
          $user_id,
          mysqli_real_escape_string($conn,(string)$wallet_id),
          $payout_sql,
          mysqli_real_escape_string($conn,$cardRef),
          mysqli_real_escape_string($conn,$cardRef)
        );
        if(!mysqli_query($conn,$ins)) throw new Exception('Tx log failed');

        mysqli_commit($conn);
        $results[] = ['ref'=>$cardRef,'ok'=>true,'msg'=>'Approved & credited'];
      } else { // decline
        if(in_array($status, ['DECLINED','FAILED','REJECTED'], true)){
          mysqli_commit($conn);
          $results[] = ['ref'=>$cardRef,'ok'=>true,'msg'=>'Already declined'];
          continue;
        }
        $u1 = "UPDATE card_trade SET trade_status='DECLINED' WHERE trade_id={$trade_id} LIMIT 1";
        if(!mysqli_query($conn,$u1)) throw new Exception('Decline failed');

        mysqli_commit($conn);
        $results[] = ['ref'=>$cardRef,'ok'=>true,'msg'=>'Declined'];
      }
    }catch(Throwable $ex){
      mysqli_rollback($conn);
      $results[] = ['ref'=>$cardRef,'ok'=>false,'msg'=>$ex->getMessage()];
    }
  }

  $okAll = count(array_filter($results, fn($r)=>$r['ok'])) === count($results);
  out(['success'=>$okAll,'results'=>$results]);

}catch(Throwable $e){ out(['success'=>false,'message'=>'Server error','_err'=>substr($e->getMessage(),0,200)],500); }

Выполнить команду


Для локальной разработки. Не используйте в интернете!