Snippets Collections
- name: ls -a via ssh
  uses: garygrossgarten/github-action-ssh@release
  with:
    command: ls -a
    host: ${{ secrets.HOST }}
    username: garygrossgarten
    passphrase: ${{ secrets.PASSPHRASE }}
    privateKey: ${{ secrets.PRIVATE_KEY}}
name: Sync Fork

on:
  schedule:
    - cron: '*/30 * * * *' # every 30 minutes
  workflow_dispatch: # on button click

jobs:
  sync:

    runs-on: ubuntu-latest

    steps:
      - uses: tgymnich/fork-sync@v2.0
        with:
          token: ${{ secrets.PERSONAL_TOKEN }}
          owner: llvm
          base: master
          head: master
# Add 'root' label to any root file changes
# Quotation marks are required for the leading asterisk
root:
- changed-files:
  - any-glob-to-any-file: '*'

# Add 'AnyChange' label to any changes within the entire repository
AnyChange:
- changed-files:
  - any-glob-to-any-file: '**'

# Add 'Documentation' label to any changes within 'docs' folder or any subfolders
Documentation:
- changed-files:
  - any-glob-to-any-file: docs/**

# Add 'Documentation' label to any file changes within 'docs' folder
Documentation:
- changed-files:
  - any-glob-to-any-file: docs/*

# Add 'Documentation' label to any file changes within 'docs' or 'guides' folders
Documentation:
- changed-files:
  - any-glob-to-any-file:
    - docs/*
    - guides/*

## Equivalent of the above mentioned configuration using another syntax
Documentation:
- changed-files:
  - any-glob-to-any-file: ['docs/*', 'guides/*']

# Add 'Documentation' label to any change to .md files within the entire repository 
Documentation:
- changed-files:
  - any-glob-to-any-file: '**/*.md'

# Add 'source' label to any change to src files within the source dir EXCEPT for the docs sub-folder
source:
- all:
  - changed-files:
    - any-glob-to-any-file: 'src/**/*'
    - all-globs-to-all-files: '!src/docs/*'

# Add 'feature' label to any PR where the head branch name starts with `feature` or has a `feature` section in the name
feature:
 - head-branch: ['^feature', 'feature']

# Add 'release' label to any PR that is opened against the `main` branch
release:
 - base-branch: 'main'
jobs:
  run:
    runs-on: ${{ matrix.operating-system }}
    strategy:
      matrix:
        operating-system: ['ubuntu-latest', 'windows-latest', 'macos-latest']
        php-versions: ['8.1', '8.2', '8.3']
        phpunit-versions: ['latest']
        include:
          - operating-system: 'ubuntu-latest'
            php-versions: '8.0'
            phpunit-versions: 9
    steps:
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: ${{ matrix.php-versions }}
        extensions: mbstring, intl
        ini-values: post_max_size=256M, max_execution_time=180
        coverage: xdebug
        tools: php-cs-fixer, phpunit:${{ matrix.phpunit-versions }}
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  {
    "op": "CustomVal",
    "searchfor": "MAX_CONSECUTIVE_LOW_TEMPERATURE_ERROR_ALLOWED",
    "value": "10",
    "comment": "Fixes MINTEMP issue caused by unstable temperature readings"
  }
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [ 14, 16, 18 ]
    name: Node ${{ matrix.node }} sample
    steps:
      - uses: actions/checkout@v4
      - name: Setup node
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

# GitHub recommends pinning actions to a commit SHA.
# To get a newer version, you will need to update the SHA.
# You can also reference a tag or branch, but the action may change without warning.

on:
  push:
    branches:
      - main

env:
  AZURE_WEBAPP_NAME: MY_WEBAPP_NAME   # set this to your application's name
  AZURE_WEBAPP_PACKAGE_PATH: '.'      # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: '14.x'                # set this to the node version to use

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Set up Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'

    - name: npm install, build, and test
      run: |
        npm install
        npm run build --if-present
        npm run test --if-present
    - name: Upload artifact for deployment job
      uses: actions/upload-artifact@v4
      with:
        name: node-app
        path: .

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
    - name: Download artifact from build job
      uses: actions/download-artifact@v4
      with:
        name: node-app

    - name: 'Deploy to Azure WebApp'
      id: deploy-to-webapp
      uses: azure/webapps-deploy@85270a1854658d167ab239bce43949edb336fa7c
      with:
        app-name: ${{ env.AZURE_WEBAPP_NAME }}
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["pypy3.9", "pypy3.10", "3.9", "3.10", "3.11", "3.12"]

    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      # You can test your matrix by printing the current Python version
      - name: Display Python version
        run: python -c "import sys; print(sys.version)"
if (!function_exists('dd')) {
    function dd(...$vars)
    {
        // ألوان مختلفة ومتناغمة
        $colors = [
            '#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#c2c2f0',
            '#ffb3e6', '#c2f0c2', '#ffccff', '#ffb3b3', '#c2c2c2'
        ];
        $colorCount = count($colors);
        
        // الحصول على معلومات إضافية
        $backtrace = debug_backtrace();
        $debugInfo = [
            'line' => $backtrace[0]['line'],
            'file' => $backtrace[0]['file'],
            'function' => $backtrace[1]['function'] ?? 'N/A',
            'request' => $_REQUEST,
            'session' => $_SESSION ?? []
        ];

        // عرض المعلومات الافتراضية إذا لم يتم تمرير أي متغيرات
        if (empty($vars)) {
            $vars[] = [
                'file' => $debugInfo['file'],
                'line' => $debugInfo['line'],
                'function' => $debugInfo['function'],
                'request' => $debugInfo['request'],
                'session' => $debugInfo['session'],
            ];
        }

        echo '<div style="font-family: Arial, sans-serif; line-height: 1.5;">';
        
        foreach ($vars as $index => $var) {
            // حدد اللون بناءً على الفهرس
            $color = $colors[$index % $colorCount];
            
            echo '<div style="background-color: ' . $color . '; padding: 10px; border-radius: 5px; margin-bottom: 10px; color: #fff;">';
            
            // عنوان البلوك
            echo '<strong>Breakpoint (' . $debugInfo['file'] . ' on line ' . $debugInfo['line'] . ') ---> Function: ' . $debugInfo['function'] . '</strong><br>';
            echo '<strong>Request Data:</strong><br>';
            echo '<pre>' . json_encode($debugInfo['request'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</pre>';
            echo '<strong>Session Data:</strong><br>';
            echo '<pre>' . json_encode($debugInfo['session'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</pre>';
            
            // عرض المتغيرات
            echo '<strong>Variable ' . ($index + 1) . ':</strong><br>';
            if (is_array($var) || is_object($var)) {
                echo '<pre>' . json_encode($var, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . '</pre>';
            } elseif (is_bool($var) || is_null($var)) {
                var_dump($var);
            } else {
                echo htmlspecialchars($var, ENT_QUOTES, 'UTF-8');
            }
            
            echo '</div>';
        }
        
        echo '</div>';
        die(1);
    }
}
<?php
namespace App\Http\Controllers\Callback;

use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use Razorpay\Api\Api;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use Illuminate\Support\Str;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;

class RazorpayController extends Controller
{
    public $gateway = "razorpay";
    public $status  = "paid";
    public $settings;


    /**
     * Payment gateway callback
     *
     * @param Request $request
     * @return mixed
     */
    public function callback(Request $request)
    {
        try {
            
            // Get payment gateway settings
            $settings       = AutomaticPaymentGateway::where('slug', $this->gateway)
                                                     ->where('is_active', true)
                                                     ->firstOrFail();

            // Set settings
            $this->settings = $settings;

            // Get payment id
            $payment_id     = $request->get('payment_id');

            // Get order id
            $order_id       = $request->get('order_id');

            // Get signature
            $signature      = $request->get('signature');

            // Get action
            $action         = $request->get('action');

            // Check webhook event
            if ( $payment_id && $order_id && $signature ) {

                // Check if payment succeeded
                $response = $this->verify($payment_id, $order_id, $signature);

                // Check if payment succeeded
                if ( is_array($response) && $response['success'] === TRUE) {

                    // Check if deposit callback
                    if ($action === "D") {
                        
                        // Get saved webhook data in our database
                        $data = DepositWebhook::where('payment_id', $order_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
        
                        // Handle deposit callback
                        $this->deposit($data->user_id, $data->amount, $order_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('deposit');

                    }
    
                    // Check if checkout callback
                    if ($action === "G") {
                        
                        // Get saved webhook data in our database
                        $data = CheckoutWebhook::where('payment_id', $order_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
    
                        // Get cart
                        $cart = $data->data['cart'];
    
                        // Get user
                        $user = User::where('id', $data->data['buyer_id'])->firstOrFail();
        
                        // Handle deposit callback
                        $this->checkout($cart, $user, $order_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('gigs');
    
                    }

                }

            }

            // In case failed redirect to home page
            return redirect('/');

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Verify if payment succeeded
     *
     * @param string $id
     * @return array
     */
    private function verify($payment_id, $order_id, $signature)
    {
        try {

            // Get payment gateway keys
            $key_id        = $this->settings?->settings['key_id'];
            $key_secret    = $this->settings?->settings['key_secret'];

            // Set api
            $api           = new Api($key_id, $key_secret);

            // Let's verify first the signature
            $api->utility->verifyPaymentSignature([
                'razorpay_signature'  => $signature,
                'razorpay_payment_id' => $payment_id,
                'razorpay_order_id'   => $order_id
            ]);

            // Fetch this payment
            $fetch_payment = $api->payment->fetch($payment_id);

            // Check if payment authorized
            if ($fetch_payment->status === 'authorized') {
                
                // Let capture this payment
                $payment = $api->payment->fetch($payment_id)->capture([
                    'amount'   => $fetch_payment->amount,
                    'currency' => $fetch_payment->currency
                ]);

            } else if ($fetch_payment->status === 'captured') {
                
                // Set payment
                $payment = $fetch_payment;

            } else {

                // Payment failed
                return [
                    'success'  => false,
                    'message'  => __('messages.t_we_could_not_handle_ur_payment')
                ];

            }

            // Check if payment succeeded
            if ( $payment && $payment->status === 'captured' ) {
                
                // Done
                return [
                    'success'  => true,
                    'response' => $payment
                ];

            } else {

                // Failed
                return [
                    'success' => false,
                    'message' => __('messages.t_error_stripe_payment_failed')
                ];

            }

        } catch (\Throwable $th) {
            
            // Error
            return [
                'success' => false,
                'message' => __('messages.t_toast_something_went_wrong')
            ];

        }
    }


    /**
     * Deposit funds into user's account
     *
     * @param int $user_id
     * @param mixed $amount
     * @param string $payment_id
     * @return void
     */
    private function deposit($user_id, $amount, $payment_id)
    {
        try {
            
            // Set amount
            $amount                  = convertToNumber($amount);
            
            // Calculate fee from this amount
            $fee                     = convertToNumber($this->fee('deposit', $amount)); 

            // Make transaction
            $deposit                 = new DepositTransaction();
            $deposit->user_id        = $user_id;
            $deposit->transaction_id = $payment_id;
            $deposit->payment_method = $this->gateway;
            $deposit->amount_total   = $amount;
            $deposit->amount_fee     = $fee;
            $deposit->amount_net     = $amount - $fee;
            $deposit->currency       = $this->settings->currency;
            $deposit->exchange_rate  = $this->settings->exchange_rate;
            $deposit->status         = $this->status;
            $deposit->ip_address     = request()->ip();
            $deposit->save();

            // Get user
            $user                    = User::where('id', $user_id)->firstOrFail();

            // Add funds
            $user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
            $user->save();

            // Send  a notification
            $this->notification('deposit', $user);

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Checkout
     *
     * @param array $cart
     * @param object $user
     * @param string $payment_id
     * @return void
     */
    private function checkout($cart, $user, $payment_id)
    {
        try {

            // Set empty variables
            $subtotal = 0;
            $total    = 0;
            $tax      = 0;
            $fee      = 0;

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Add gig price to subtotal
                $subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);

                // Check if item has upgrades
                $upgrades  = $item['upgrades'];

                // Loop through upgrades
                if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
                    
                    // Loop through upgrades
                    foreach ($upgrades as $j => $upgrade) {
                        
                        // Check if upgrade checked
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            // Add upgrade price to subtotal
                            $subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);

                        }

                    }

                }

            }

            // Get commission settings
            $commission_settings = settings('commission');

            // Check if taxes enabled
            if ($commission_settings->enable_taxes) {
                
                // Check if type of taxes percentage
                if ($commission_settings->tax_type === 'percentage') {
                    
                    // Set tax amount
                    $tax       = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);

                } else {
                    
                    // Set tax amount
                    $tax       = convertToNumber($commission_settings->tax_value);

                }

            }

            // Calculate payment gateway fee
            $fee                   = convertToNumber($this->fee( 'gigs', $subtotal ));
            
            // Calculate total price
            $total                 = $subtotal + $tax + $fee;
        
            // Get user billing address
            $billing_info          = $user->billing;

            // Set unique id for this order
            $uid                   = uid();

            // Get buyer id
            $buyer_id              = $user->id;

            // Save order
            $order                 = new Order();
            $order->uid            = $uid;
            $order->buyer_id       = $buyer_id;
            $order->total_value    = $total;
            $order->subtotal_value = $subtotal;
            $order->taxes_value    = $tax;
            $order->save();

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Get gig
                $gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();

                // Check if gig exists
                if ($gig) {
                    
                    // Set quantity
                    $quantity        = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;

                    // Set gig upgrades
                    $upgrades        = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];

                    // Set empty variable
                    $upgrades_amount = 0;

                    // Loop through upgrades
                    foreach ($upgrades as $index => $upgrade) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            $upgrades_amount += convertToNumber($upgrade['price']) * $quantity;

                        }

                    }

                    // Set item total price
                    $item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );

                    // Calculate commission first
                    if ($commission_settings->commission_from === 'orders') {
                        
                        // Check commission type
                        if ($commission_settings->commission_type === 'percentage') {
                            
                            // Calculate commission
                            $commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
    
                        } else {
    
                            // Fixed amount
                            $commission = convertToNumber($commission_settings->commission_value);
    
                        }

                    } else {
                        
                        // No commission
                        $commission = 0;

                    }

                    // Save order item
                    $order_item                         = new OrderItem();
                    $order_item->uid                    = uid();
                    $order_item->order_id               = $order->id;
                    $order_item->gig_id                 = $gig->id;
                    $order_item->owner_id               = $gig->user_id;
                    $order_item->quantity               = $quantity;
                    $order_item->has_upgrades           = count($upgrades) ? true : false;
                    $order_item->total_value            = $item_total;
                    $order_item->profit_value           = $item_total - $commission;
                    $order_item->commission_value       = $commission;
                    $order_item->save();

                    // Loop through upgrades again
                    foreach ($upgrades as $index => $value) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                        
                            // Get upgrade
                            $upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
    
                            // Check if upgrade exists
                            if ($upgrade) {
                                
                                // Save item upgrade
                                $order_item_upgrade             = new OrderItemUpgrade();
                                $order_item_upgrade->item_id    = $order_item->id;
                                $order_item_upgrade->title      = $upgrade->title;
                                $order_item_upgrade->price      = $upgrade->price;
                                $order_item_upgrade->extra_days = $upgrade->extra_days;
                                $order_item_upgrade->save();
    
                            }

                        }
                        
                    }

                    // Update seller pending balance
                    $gig->owner()->update([
                        'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
                    ]);

                    // Increment orders in queue
                    $gig->increment('orders_in_queue');

                    // Order item placed successfully
                    // Let's notify the seller about new order
                    $gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );

                    // Check user's level
                    check_user_level($buyer_id);

                    // Send notification
                    notification([
                        'text'    => 't_u_received_new_order_seller',
                        'action'  => url('seller/orders/details', $order_item->uid),
                        'user_id' => $order_item->owner_id
                    ]);

                }

            }

            // Save invoice
            $invoice                 = new OrderInvoice();
            $invoice->order_id       = $order->id;
            $invoice->payment_method = $this->gateway;
            $invoice->payment_id     = $payment_id;
            $invoice->firstname      = $billing_info->firstname ?? $user->username;
            $invoice->lastname       = $billing_info->lastname ?? $user->username;
            $invoice->email          = $user->email;
            $invoice->company        = !empty($billing_info->company) ? clean($billing_info->company) : null;
            $invoice->address        = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
            $invoice->status         = 'paid';
            $invoice->save();

            // Update balance
            $user->update([
                'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
            ]);

            // Now everything succeeded
            // Let's empty the cart
            session()->forget('cart');

            // Now let's notify the buyer that his order has been placed
            $user->notify( (new OrderPlaced($order))->locale(config('app.locale')) );

        } catch (\Throwable $th) {
            
            // Error
            throw $th;

        }
    }


    /**
     * Calculate fee value
     *
     * @param string $type
     * @param mixed $amount
     * @return mixed
     */
    private function fee($type, $amount = null)
    {
        try {
            
            // Set amount for deposit
            $amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;

            // Remove long decimal
            $amount = convertToNumber( number_format($amount, 2, '.', '') );

            // Check fee type
            switch ($type) {
    
                // Deposit
                case 'deposit':
    
                    // Get deposit fixed fee
                    if (isset($this->settings->fixed_fee['deposit'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get deposit percentage fee
                    if (isset($this->settings->percentage_fee['deposit'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
                    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
                    
                    // Return fee value
                    return number_format($fee_value, 2, '.', '');
    
                break;

                // Gigs
                case 'gigs':

                    // Get gigs fixed fee
                    if (isset($this->settings->fixed_fee['gigs'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get gigs percentage fee
                    if (isset($this->settings->percentage_fee['gigs'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
    
                    // Return fee value
                    return $fee_value;

                break;
    
            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return 0;

        }
    }


    /**
     * Calculate exchange rate
     *
     * @param mixed $amount
     * @param mixed $exchange_rate
     * @param boolean $formatted
     * @param string $currency
     * @return mixed
     */
    private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
    {
        try {

            // Convert amount to number
            $amount                = convertToNumber($amount);

            // Get currency settings
            $currency_settings     = settings('currency');

            // Get default currency exchange rate
            $default_exchange_rate = convertToNumber($currency_settings->exchange_rate);

            // Get exchanged amount
            $exchanged_amount      = convertToNumber( $amount *  $default_exchange_rate / $exchange_rate );

            // Check if we have to return a formatted value
            if ($formatted) {
                
                return money( $exchanged_amount, $currency, true )->format();

            }

            // Return max deposit
            return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));

        } catch (\Throwable $th) {

            // Something went wrong
            return $amount;

        }
    }


    /**
     * Send a notification to user
     *
     * @param string $type
     * @param object $user
     * @return void
     */
    private function notification($type, $user)
    {
        try {
            
            // Check notification type
            switch ($type) {

                // Deposit funds
                case 'deposit':
                    


                break;

                // Gig checkout
                case 'gig':
                    
                    

                break;

                // Project payment
                case 'project':
                    
                    

                break;

                // Bid payment
                case 'bid':
                    
                    

                break;

            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return;

        }
    }


    /**
     * Redirecting
     *
     * @param string $type
     * @param string $status
     * @return void
     */
    private function redirect($type, $status = 'success')
    {
        // Check where to redirect
        switch ($type) {

            // Deposit history
            case 'deposit':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));

                }
                

            break;

            // Gigs order
            case 'gigs':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));

                }

            break;

        }
    }
}
<?php
namespace App\Http\Controllers\Callback;

use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;

class PaymobPkController extends Controller
{
    public $gateway = "paymob-pk";
    public $status  = "paid";
    public $settings;


    /**
     * Payment gateway callback
     *
     * @param Request $request
     * @return mixed
     */
    public function callback(Request $request)
    {
        try {
            
            // Get payment gateway settings
            $settings       = AutomaticPaymentGateway::where('slug', $this->gateway)
                                                     ->where('is_active', true)
                                                     ->firstOrFail();

            // Set settings
            $this->settings = $settings;

            // Get transaction id
            $transaction_id = $request->get('id');

            // Check webhook event
            if ( $transaction_id ) {

                // Check if payment succeeded
                $response = $this->verify($transaction_id);
                
                // Check if payment succeeded
                if ( is_array($response) && $response['success'] === TRUE) {
                    
                    // Get action
                    $action   = $response['response']['obj']['order']['shipping_data']['shipping_method'];

                    // Check if deposit callback
                    if ( isset($action) && $action === "D" ) {
                        
                        // Get saved webhook data in our database
                        $data = DepositWebhook::where('payment_id', $transaction_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
        
                        // Handle deposit callback
                        $this->deposit($data->user_id, $data->amount, $transaction_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('deposit');

                    }
    
                    // Check if checkout callback
                    if ( isset($action) && $action === "G" ) {
                        
                        // Get saved webhook data in our database
                        $data = CheckoutWebhook::where('payment_id', $transaction_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
    
                        // Get cart
                        $cart = $data->data['cart'];
    
                        // Get user
                        $user = User::where('id', $data->data['buyer_id'])->firstOrFail();
        
                        // Handle deposit callback
                        $this->checkout($cart, $user, $transaction_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('gigs');
    
                    }

                }

            }

            // In case failed redirect to home page
            return redirect('/');

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Verify if payment succeeded
     *
     * @param string $id
     * @return array
     */
    private function verify($id)
    {
        try {

            // Get auth token
            $auth    = Http::acceptJson()->post('https://pakistan.paymob.com/api/auth/tokens', [
                                            'api_key' => $this->settings?->settings['api_key'],
                                        ])->json();

            // Check if token is set
            if (isset($auth['token'])) {

                // Get payment details
                $payment = Http::withToken($auth['token'])
                                ->get("https://pakistan.paymob.com/api/acceptance/transactions/$id")
                                ->json();

                // Check if payment succeeded
                if ( is_array($payment) && isset($payment['obj']['success']) && $payment['obj']['success'] == true ) {
                    
                    // Done
                    return [
                        'success'  => true,
                        'response' => $payment
                    ];

                } else {

                    // Failed
                    return [
                        'success' => false,
                        'message' => __('messages.t_error_stripe_payment_failed')
                    ];

                }

            } else {

                // Failed
                return [
                    'success' => false,
                    'message' => __('messages.t_error_stripe_payment_failed')
                ];

            }

        } catch (\Throwable $th) {
            
            // Error
            return [
                'success' => false,
                'message' => __('messages.t_toast_something_went_wrong')
            ];

        }
    }


    /**
     * Deposit funds into user's account
     *
     * @param int $user_id
     * @param mixed $amount
     * @param string $payment_id
     * @return void
     */
    private function deposit($user_id, $amount, $payment_id)
    {
        try {
            
            // Set amount
            $amount                  = convertToNumber($amount);
            
            // Calculate fee from this amount
            $fee                     = convertToNumber($this->fee('deposit', $amount)); 

            // Make transaction
            $deposit                 = new DepositTransaction();
            $deposit->user_id        = $user_id;
            $deposit->transaction_id = $payment_id;
            $deposit->payment_method = $this->gateway;
            $deposit->amount_total   = $amount;
            $deposit->amount_fee     = $fee;
            $deposit->amount_net     = $amount - $fee;
            $deposit->currency       = $this->settings->currency;
            $deposit->exchange_rate  = $this->settings->exchange_rate;
            $deposit->status         = $this->status;
            $deposit->ip_address     = request()->ip();
            $deposit->save();

            // Get user
            $user                    = User::where('id', $user_id)->firstOrFail();

            // Add funds
            $user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
            $user->save();

            // Send  a notification
            $this->notification('deposit', $user);

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Checkout
     *
     * @param array $cart
     * @param object $user
     * @param string $payment_id
     * @return void
     */
    private function checkout($cart, $user, $payment_id)
    {
        try {

            // Set empty variables
            $subtotal = 0;
            $total    = 0;
            $tax      = 0;
            $fee      = 0;

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Add gig price to subtotal
                $subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);

                // Check if item has upgrades
                $upgrades  = $item['upgrades'];

                // Loop through upgrades
                if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
                    
                    // Loop through upgrades
                    foreach ($upgrades as $j => $upgrade) {
                        
                        // Check if upgrade checked
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            // Add upgrade price to subtotal
                            $subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);

                        }

                    }

                }

            }

            // Get commission settings
            $commission_settings = settings('commission');

            // Check if taxes enabled
            if ($commission_settings->enable_taxes) {
                
                // Check if type of taxes percentage
                if ($commission_settings->tax_type === 'percentage') {
                    
                    // Set tax amount
                    $tax       = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);

                } else {
                    
                    // Set tax amount
                    $tax       = convertToNumber($commission_settings->tax_value);

                }

            }

            // Calculate payment gateway fee
            $fee                   = convertToNumber($this->fee( 'gigs', $subtotal ));
            
            // Calculate total price
            $total                 = $subtotal + $tax + $fee;
        
            // Get user billing address
            $billing_info          = $user->billing;

            // Set unique id for this order
            $uid                   = uid();

            // Get buyer id
            $buyer_id              = $user->id;

            // Save order
            $order                 = new Order();
            $order->uid            = $uid;
            $order->buyer_id       = $buyer_id;
            $order->total_value    = $total;
            $order->subtotal_value = $subtotal;
            $order->taxes_value    = $tax;
            $order->save();

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Get gig
                $gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();

                // Check if gig exists
                if ($gig) {
                    
                    // Set quantity
                    $quantity        = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;

                    // Set gig upgrades
                    $upgrades        = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];

                    // Set empty variable
                    $upgrades_amount = 0;

                    // Loop through upgrades
                    foreach ($upgrades as $index => $upgrade) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            $upgrades_amount += convertToNumber($upgrade['price']) * $quantity;

                        }

                    }

                    // Set item total price
                    $item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );

                    // Calculate commission first
                    if ($commission_settings->commission_from === 'orders') {
                        
                        // Check commission type
                        if ($commission_settings->commission_type === 'percentage') {
                            
                            // Calculate commission
                            $commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
    
                        } else {
    
                            // Fixed amount
                            $commission = convertToNumber($commission_settings->commission_value);
    
                        }

                    } else {
                        
                        // No commission
                        $commission = 0;

                    }

                    // Save order item
                    $order_item                         = new OrderItem();
                    $order_item->uid                    = uid();
                    $order_item->order_id               = $order->id;
                    $order_item->gig_id                 = $gig->id;
                    $order_item->owner_id               = $gig->user_id;
                    $order_item->quantity               = $quantity;
                    $order_item->has_upgrades           = count($upgrades) ? true : false;
                    $order_item->total_value            = $item_total;
                    $order_item->profit_value           = $item_total - $commission;
                    $order_item->commission_value       = $commission;
                    $order_item->save();

                    // Loop through upgrades again
                    foreach ($upgrades as $index => $value) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                        
                            // Get upgrade
                            $upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
    
                            // Check if upgrade exists
                            if ($upgrade) {
                                
                                // Save item upgrade
                                $order_item_upgrade             = new OrderItemUpgrade();
                                $order_item_upgrade->item_id    = $order_item->id;
                                $order_item_upgrade->title      = $upgrade->title;
                                $order_item_upgrade->price      = $upgrade->price;
                                $order_item_upgrade->extra_days = $upgrade->extra_days;
                                $order_item_upgrade->save();
    
                            }

                        }
                        
                    }

                    // Update seller pending balance
                    $gig->owner()->update([
                        'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
                    ]);

                    // Increment orders in queue
                    $gig->increment('orders_in_queue');

                    // Order item placed successfully
                    // Let's notify the seller about new order
                    $gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );

                    // Check user's level
                    check_user_level($buyer_id);

                    // Send notification
                    notification([
                        'text'    => 't_u_received_new_order_seller',
                        'action'  => url('seller/orders/details', $order_item->uid),
                        'user_id' => $order_item->owner_id
                    ]);

                }

            }

            // Save invoice
            $invoice                 = new OrderInvoice();
            $invoice->order_id       = $order->id;
            $invoice->payment_method = $this->gateway;
            $invoice->payment_id     = $payment_id;
            $invoice->firstname      = $billing_info->firstname ?? $user->username;
            $invoice->lastname       = $billing_info->lastname ?? $user->username;
            $invoice->email          = $user->email;
            $invoice->company        = !empty($billing_info->company) ? clean($billing_info->company) : null;
            $invoice->address        = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
            $invoice->status         = 'paid';
            $invoice->save();

            // Update balance
            $user->update([
                'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
            ]);

            // Now everything succeeded
            // Let's empty the cart
            session()->forget('cart');

            // Now let's notify the buyer that his order has been placed
            $user->notify( (new OrderPlaced($order))->locale(config('app.locale')) );

        } catch (\Throwable $th) {
            
            // Error
            throw $th;

        }
    }


    /**
     * Calculate fee value
     *
     * @param string $type
     * @param mixed $amount
     * @return mixed
     */
    private function fee($type, $amount = null)
    {
        try {
            
            // Set amount for deposit
            $amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;

            // Remove long decimal
            $amount = convertToNumber( number_format($amount, 2, '.', '') );

            // Check fee type
            switch ($type) {
    
                // Deposit
                case 'deposit':
    
                    // Get deposit fixed fee
                    if (isset($this->settings->fixed_fee['deposit'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get deposit percentage fee
                    if (isset($this->settings->percentage_fee['deposit'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
                    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
                    
                    // Return fee value
                    return number_format($fee_value, 2, '.', '');
    
                break;

                // Gigs
                case 'gigs':

                    // Get gigs fixed fee
                    if (isset($this->settings->fixed_fee['gigs'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get gigs percentage fee
                    if (isset($this->settings->percentage_fee['gigs'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
    
                    // Return fee value
                    return $fee_value;

                break;
    
            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return 0;

        }
    }


    /**
     * Calculate exchange rate
     *
     * @param mixed $amount
     * @param mixed $exchange_rate
     * @param boolean $formatted
     * @param string $currency
     * @return mixed
     */
    private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
    {
        try {

            // Convert amount to number
            $amount                = convertToNumber($amount);

            // Get currency settings
            $currency_settings     = settings('currency');

            // Get default currency exchange rate
            $default_exchange_rate = convertToNumber($currency_settings->exchange_rate);

            // Get exchanged amount
            $exchanged_amount      = convertToNumber( $amount *  $default_exchange_rate / $exchange_rate );

            // Check if we have to return a formatted value
            if ($formatted) {
                
                return money( $exchanged_amount, $currency, true )->format();

            }

            // Return max deposit
            return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));

        } catch (\Throwable $th) {

            // Something went wrong
            return $amount;

        }
    }


    /**
     * Send a notification to user
     *
     * @param string $type
     * @param object $user
     * @return void
     */
    private function notification($type, $user)
    {
        try {
            
            // Check notification type
            switch ($type) {

                // Deposit funds
                case 'deposit':
                    


                break;

                // Gig checkout
                case 'gig':
                    
                    

                break;

                // Project payment
                case 'project':
                    
                    

                break;

                // Bid payment
                case 'bid':
                    
                    

                break;

            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return;

        }
    }


    /**
     * Redirecting
     *
     * @param string $type
     * @param string $status
     * @return void
     */
    private function redirect($type, $status = 'success')
    {
        // Check where to redirect
        switch ($type) {

            // Deposit history
            case 'deposit':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));

                }
                

            break;

            // Gigs order
            case 'gigs':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));

                }

            break;

        }
    }
}
<?php
namespace App\Http\Controllers\Callback;

use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use Illuminate\Support\Str;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;

class FlutterwaveController extends Controller
{
    public $gateway = "flutterwave";
    public $status  = "paid";
    public $settings;


    /**
     * Payment gateway callback
     *
     * @param Request $request
     * @return mixed
     */
    public function callback(Request $request)
    {
        try {
            
            // Get payment gateway settings
            $settings       = AutomaticPaymentGateway::where('slug', $this->gateway)
                                                     ->where('is_active', true)
                                                     ->firstOrFail();

            // Set settings
            $this->settings = $settings;

            // Get transaction id
            $transaction_id = $request->get('transaction_id');

            // Check webhook event
            if ( $transaction_id ) {

                // Check if payment succeeded
                $response = $this->verify($transaction_id);
                
                // Check if payment succeeded
                if ( is_array($response) && $response['success'] === TRUE) {
                    
                    // Get order id
                    $order_id = $response['response']['data']['tx_ref'];

                    // Check if deposit callback
                    if (Str::startsWith($order_id, "DD")) {
                        
                        // Get saved webhook data in our database
                        $data = DepositWebhook::where('payment_id', $order_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
        
                        // Handle deposit callback
                        $this->deposit($data->user_id, $data->amount, $order_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('deposit');

                    }
    
                    // Check if checkout callback
                    if (Str::startsWith($order_id, "GG")) {
                        
                        // Get saved webhook data in our database
                        $data = CheckoutWebhook::where('payment_id', $order_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
    
                        // Get cart
                        $cart = $data->data['cart'];
    
                        // Get user
                        $user = User::where('id', $data->data['buyer_id'])->firstOrFail();
        
                        // Handle deposit callback
                        $this->checkout($cart, $user, $order_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('gigs');
    
                    }

                }

            }

            // In case failed redirect to home page
            return redirect('/');

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Verify if payment succeeded
     *
     * @param string $id
     * @return array
     */
    private function verify($id)
    {
        try {

            // Get payment gateway keys
            $secret_key = $this->settings?->settings['secret_key'];

            $response   = Http::withHeaders([
                                    'Authorization' => 'Bearer ' . $secret_key,
                                    'Accept'        => 'application/json',
                                ])->get("https://api.flutterwave.com/v3/transactions/$id/verify")->json();

            // Check if payment succeeded
            if ( is_array($response) && $response['status'] === 'success' ) {
                
                // Done
                return [
                    'success'  => true,
                    'response' => $response
                ];

            } else {

                // Failed
                return [
                    'success' => false,
                    'message' => __('messages.t_error_stripe_payment_failed')
                ];

            }

        } catch (\Throwable $th) {
            
            // Error
            return [
                'success' => false,
                'message' => __('messages.t_toast_something_went_wrong')
            ];

        }
    }


    /**
     * Deposit funds into user's account
     *
     * @param int $user_id
     * @param mixed $amount
     * @param string $payment_id
     * @return void
     */
    private function deposit($user_id, $amount, $payment_id)
    {
        try {
            
            // Set amount
            $amount                  = convertToNumber($amount);
            
            // Calculate fee from this amount
            $fee                     = convertToNumber($this->fee('deposit', $amount)); 

            // Make transaction
            $deposit                 = new DepositTransaction();
            $deposit->user_id        = $user_id;
            $deposit->transaction_id = $payment_id;
            $deposit->payment_method = $this->gateway;
            $deposit->amount_total   = $amount;
            $deposit->amount_fee     = $fee;
            $deposit->amount_net     = $amount - $fee;
            $deposit->currency       = $this->settings->currency;
            $deposit->exchange_rate  = $this->settings->exchange_rate;
            $deposit->status         = $this->status;
            $deposit->ip_address     = request()->ip();
            $deposit->save();

            // Get user
            $user                    = User::where('id', $user_id)->firstOrFail();

            // Add funds
            $user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
            $user->save();

            // Send  a notification
            $this->notification('deposit', $user);

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Checkout
     *
     * @param array $cart
     * @param object $user
     * @param string $payment_id
     * @return void
     */
    private function checkout($cart, $user, $payment_id)
    {
        try {

            // Set empty variables
            $subtotal = 0;
            $total    = 0;
            $tax      = 0;
            $fee      = 0;

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Add gig price to subtotal
                $subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);

                // Check if item has upgrades
                $upgrades  = $item['upgrades'];

                // Loop through upgrades
                if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
                    
                    // Loop through upgrades
                    foreach ($upgrades as $j => $upgrade) {
                        
                        // Check if upgrade checked
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            // Add upgrade price to subtotal
                            $subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);

                        }

                    }

                }

            }

            // Get commission settings
            $commission_settings = settings('commission');

            // Check if taxes enabled
            if ($commission_settings->enable_taxes) {
                
                // Check if type of taxes percentage
                if ($commission_settings->tax_type === 'percentage') {
                    
                    // Set tax amount
                    $tax       = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);

                } else {
                    
                    // Set tax amount
                    $tax       = convertToNumber($commission_settings->tax_value);

                }

            }

            // Calculate payment gateway fee
            $fee                   = convertToNumber($this->fee( 'gigs', $subtotal ));
            
            // Calculate total price
            $total                 = $subtotal + $tax + $fee;
        
            // Get user billing address
            $billing_info          = $user->billing;

            // Set unique id for this order
            $uid                   = uid();

            // Get buyer id
            $buyer_id              = $user->id;

            // Save order
            $order                 = new Order();
            $order->uid            = $uid;
            $order->buyer_id       = $buyer_id;
            $order->total_value    = $total;
            $order->subtotal_value = $subtotal;
            $order->taxes_value    = $tax;
            $order->save();

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Get gig
                $gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();

                // Check if gig exists
                if ($gig) {
                    
                    // Set quantity
                    $quantity        = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;

                    // Set gig upgrades
                    $upgrades        = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];

                    // Set empty variable
                    $upgrades_amount = 0;

                    // Loop through upgrades
                    foreach ($upgrades as $index => $upgrade) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            $upgrades_amount += convertToNumber($upgrade['price']) * $quantity;

                        }

                    }

                    // Set item total price
                    $item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );

                    // Calculate commission first
                    if ($commission_settings->commission_from === 'orders') {
                        
                        // Check commission type
                        if ($commission_settings->commission_type === 'percentage') {
                            
                            // Calculate commission
                            $commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
    
                        } else {
    
                            // Fixed amount
                            $commission = convertToNumber($commission_settings->commission_value);
    
                        }

                    } else {
                        
                        // No commission
                        $commission = 0;

                    }

                    // Save order item
                    $order_item                         = new OrderItem();
                    $order_item->uid                    = uid();
                    $order_item->order_id               = $order->id;
                    $order_item->gig_id                 = $gig->id;
                    $order_item->owner_id               = $gig->user_id;
                    $order_item->quantity               = $quantity;
                    $order_item->has_upgrades           = count($upgrades) ? true : false;
                    $order_item->total_value            = $item_total;
                    $order_item->profit_value           = $item_total - $commission;
                    $order_item->commission_value       = $commission;
                    $order_item->save();

                    // Loop through upgrades again
                    foreach ($upgrades as $index => $value) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                        
                            // Get upgrade
                            $upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
    
                            // Check if upgrade exists
                            if ($upgrade) {
                                
                                // Save item upgrade
                                $order_item_upgrade             = new OrderItemUpgrade();
                                $order_item_upgrade->item_id    = $order_item->id;
                                $order_item_upgrade->title      = $upgrade->title;
                                $order_item_upgrade->price      = $upgrade->price;
                                $order_item_upgrade->extra_days = $upgrade->extra_days;
                                $order_item_upgrade->save();
    
                            }

                        }
                        
                    }

                    // Update seller pending balance
                    $gig->owner()->update([
                        'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
                    ]);

                    // Increment orders in queue
                    $gig->increment('orders_in_queue');

                    // Order item placed successfully
                    // Let's notify the seller about new order
                    $gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );

                    // Check user's level
                    check_user_level($buyer_id);

                    // Send notification
                    notification([
                        'text'    => 't_u_received_new_order_seller',
                        'action'  => url('seller/orders/details', $order_item->uid),
                        'user_id' => $order_item->owner_id
                    ]);

                }

            }

            // Save invoice
            $invoice                 = new OrderInvoice();
            $invoice->order_id       = $order->id;
            $invoice->payment_method = $this->gateway;
            $invoice->payment_id     = $payment_id;
            $invoice->firstname      = $billing_info->firstname ?? $user->username;
            $invoice->lastname       = $billing_info->lastname ?? $user->username;
            $invoice->email          = $user->email;
            $invoice->company        = !empty($billing_info->company) ? clean($billing_info->company) : null;
            $invoice->address        = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
            $invoice->status         = 'paid';
            $invoice->save();

            // Update balance
            $user->update([
                'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
            ]);

            // Now everything succeeded
            // Let's empty the cart
            session()->forget('cart');

            // Now let's notify the buyer that his order has been placed
            $user->notify( (new OrderPlaced($order))->locale(config('app.locale')) );

        } catch (\Throwable $th) {
            
            // Error
            throw $th;

        }
    }


    /**
     * Calculate fee value
     *
     * @param string $type
     * @param mixed $amount
     * @return mixed
     */
    private function fee($type, $amount = null)
    {
        try {
            
            // Set amount for deposit
            $amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;

            // Remove long decimal
            $amount = convertToNumber( number_format($amount, 2, '.', '') );

            // Check fee type
            switch ($type) {
    
                // Deposit
                case 'deposit':
    
                    // Get deposit fixed fee
                    if (isset($this->settings->fixed_fee['deposit'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get deposit percentage fee
                    if (isset($this->settings->percentage_fee['deposit'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
                    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
                    
                    // Return fee value
                    return number_format($fee_value, 2, '.', '');
    
                break;

                // Gigs
                case 'gigs':

                    // Get gigs fixed fee
                    if (isset($this->settings->fixed_fee['gigs'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get gigs percentage fee
                    if (isset($this->settings->percentage_fee['gigs'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
    
                    // Return fee value
                    return $fee_value;

                break;
    
            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return 0;

        }
    }


    /**
     * Calculate exchange rate
     *
     * @param mixed $amount
     * @param mixed $exchange_rate
     * @param boolean $formatted
     * @param string $currency
     * @return mixed
     */
    private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
    {
        try {

            // Convert amount to number
            $amount                = convertToNumber($amount);

            // Get currency settings
            $currency_settings     = settings('currency');

            // Get default currency exchange rate
            $default_exchange_rate = convertToNumber($currency_settings->exchange_rate);

            // Get exchanged amount
            $exchanged_amount      = convertToNumber( $amount *  $default_exchange_rate / $exchange_rate );

            // Check if we have to return a formatted value
            if ($formatted) {
                
                return money( $exchanged_amount, $currency, true )->format();

            }

            // Return max deposit
            return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));

        } catch (\Throwable $th) {

            // Something went wrong
            return $amount;

        }
    }


    /**
     * Send a notification to user
     *
     * @param string $type
     * @param object $user
     * @return void
     */
    private function notification($type, $user)
    {
        try {
            
            // Check notification type
            switch ($type) {

                // Deposit funds
                case 'deposit':
                    


                break;

                // Gig checkout
                case 'gig':
                    
                    

                break;

                // Project payment
                case 'project':
                    
                    

                break;

                // Bid payment
                case 'bid':
                    
                    

                break;

            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return;

        }
    }


    /**
     * Redirecting
     *
     * @param string $type
     * @param string $status
     * @return void
     */
    private function redirect($type, $status = 'success')
    {
        // Check where to redirect
        switch ($type) {

            // Deposit history
            case 'deposit':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));

                }
                

            break;

            // Gigs order
            case 'gigs':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));

                }

            break;

        }
    }
}
<?php
namespace App\Http\Controllers\Callback;

use App\Models\Gig;
use App\Models\User;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\GigUpgrade;
use Illuminate\Support\Str;
use App\Models\OrderInvoice;
use Illuminate\Http\Request;
use App\Models\DepositWebhook;
use App\Models\CheckoutWebhook;
use App\Models\OrderItemUpgrade;
use App\Models\DepositTransaction;
use App\Http\Controllers\Controller;
use App\Models\AffiliateTransaction;
use App\Models\AffiliateRegisteration;
use App\Models\AutomaticPaymentGateway;
use App\Notifications\User\Buyer\OrderPlaced;
use App\Notifications\User\Seller\PendingOrder;
use Srmklive\PayPal\Services\PayPal as PayPalClient;

class PaypalController extends Controller
{
    public $gateway = "paypal";
    public $status  = "paid";
    public $settings;


    /**
     * Payment gateway callback
     *
     * @param Request $request
     * @return mixed
     */
    public function callback(Request $request)
    {
        try {
            
            // Get payment gateway settings
            $settings       = AutomaticPaymentGateway::where('slug', $this->gateway)
                                                     ->where('is_active', true)
                                                     ->firstOrFail();

            // Set settings
            $this->settings = $settings;

            // Get transaction id
            $transaction_id = $request->get('order');

            // Check webhook event
            if ( $transaction_id ) {

                // Check if payment succeeded
                $response = $this->verify($transaction_id);
                
                // Check if payment succeeded
                if ( is_array($response) && $response['success'] === TRUE) {
                    
                    // Get order id
                    $order_id = $response['response']['purchase_units'][0]['payments']['captures'][0]['invoice_id'];

                    // Check if deposit callback
                    if (Str::startsWith($order_id, "D-")) {
                        
                        // Get saved webhook data in our database
                        $data = DepositWebhook::where('payment_id', $order_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
        
                        // Handle deposit callback
                        $this->deposit($data->user_id, $data->amount, $order_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('deposit');

                    }
    
                    // Check if checkout callback
                    if (Str::startsWith($order_id, "G-")) {
                        
                        // Get saved webhook data in our database
                        $data = CheckoutWebhook::where('payment_id', $order_id)
                                                ->where('payment_method', $this->gateway)
                                                ->where('status', 'pending')
                                                ->firstOrFail();
    
                        // Get cart
                        $cart = $data->data['cart'];
    
                        // Get user
                        $user = User::where('id', $data->data['buyer_id'])->firstOrFail();
        
                        // Handle deposit callback
                        $this->checkout($cart, $user, $order_id);

                        // Delete saved webhook data in our database
                        $data->delete();

                        // Redirecting
                        return $this->redirect('gigs');
    
                    }

                }

            }

            // In case failed redirect to home page
            return redirect('/');

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Verify if payment succeeded
     *
     * @param string $id
     * @return array
     */
    private function verify($id)
    {
        
            // Get payment gateway keys
            $client_id     = $this->settings?->settings['client_id'];
            $client_secret = $this->settings?->settings['client_secret'];
            $env           = $this->settings?->settings['env'];

            // Set gateway config
            $config = [
                'mode' => 'sandbox' ,
                'live' => [
                    'client_id'     => $client_id,
                    'client_secret' => $client_secret,
                    'app_id'        => '',
                ],
                'sandbox' => [
                    'client_id'     => $client_id,
                    'client_secret' => $client_secret,
                    'app_id'        => '',
                ],
                'payment_action' => 'Sale',
                'currency'       => $this->settings?->currency,
                'notify_url'     => 'https://2lancer.ma/paypal/notify',
                'locale'         => 'en_US',
                'validate_ssl'   => true,
            ];

            // Set paypal provider and config
            $client = new PayPalClient();
    
            // Set client credentials
            $client->setApiCredentials($config);

            // Get paypal access token
            $client->getAccessToken();

            // Capture this order
            $order  = $client->capturePaymentOrder($id);

            // Check if payment succeeded
            if ( is_array($order) && isset($order['status']) && $order['status'] === 'COMPLETED' ) {
                
                // Done
                return [
                    'success'  => true,
                    'response' => $order
                ];

            } else {

                // Failed
                return [
                    'success' => false,
                    'message' => __('messages.t_error_stripe_payment_failed')
                ];

            }

       
    }


    /**
     * Deposit funds into user's account
     *
     * @param int $user_id
     * @param mixed $amount
     * @param string $payment_id
     * @return void
     */
    private function deposit($user_id, $amount, $payment_id)
    {
        try {
            
            // Set amount
            $amount                  = convertToNumber($amount);
            
            // Calculate fee from this amount
            $fee                     = convertToNumber($this->fee('deposit', $amount)); 

            // Make transaction
            $deposit                 = new DepositTransaction();
            $deposit->user_id        = $user_id;
            $deposit->transaction_id = $payment_id;
            $deposit->payment_method = $this->gateway;
            $deposit->amount_total   = $amount;
            $deposit->amount_fee     = $fee;
            $deposit->amount_net     = $amount - $fee;
            $deposit->currency       = $this->settings->currency;
            $deposit->exchange_rate  = $this->settings->exchange_rate;
            $deposit->status         = $this->status;
            $deposit->ip_address     = request()->ip();
            $deposit->save();

            // Get user
            $user                    = User::where('id', $user_id)->firstOrFail();

            // Add funds
            $user->balance_available = convertToNumber($user->balance_available) + convertToNumber($deposit->amount_net);
            $user->save();

            // Send  a notification
            $this->notification('deposit', $user);

        } catch (\Throwable $th) {

            // Error
            throw $th;

        }
    }


    /**
     * Checkout
     *
     * @param array $cart
     * @param object $user
     * @param string $payment_id
     * @return void
     */
    private function checkout($cart, $user, $payment_id)
    {
        try {

            // Set empty variables
            $subtotal = 0;
            $total    = 0;
            $tax      = 0;
            $fee      = 0;

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Add gig price to subtotal
                $subtotal += convertToNumber($item['gig']['price']) * convertToNumber($item['quantity']);

                // Check if item has upgrades
                $upgrades  = $item['upgrades'];

                // Loop through upgrades
                if ( isset($upgrades) && is_array($upgrades) && count($upgrades) ) {
                    
                    // Loop through upgrades
                    foreach ($upgrades as $j => $upgrade) {
                        
                        // Check if upgrade checked
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            // Add upgrade price to subtotal
                            $subtotal += convertToNumber($upgrade['price']) * convertToNumber($item['quantity']);

                        }

                    }

                }

            }

            // Get commission settings
            $commission_settings = settings('commission');

            // Check if taxes enabled
            if ($commission_settings->enable_taxes) {
                
                // Check if type of taxes percentage
                if ($commission_settings->tax_type === 'percentage') {
                    
                    // Set tax amount
                    $tax       = convertToNumber(bcmul($subtotal, $commission_settings->tax_value) / 100);

                } else {
                    
                    // Set tax amount
                    $tax       = convertToNumber($commission_settings->tax_value);

                }

            }

            // Calculate payment gateway fee
            $fee                   = convertToNumber($this->fee( 'gigs', $subtotal ));
            
            // Calculate total price
            $total                 = $subtotal + $tax + $fee;
        
            // Get user billing address
            $billing_info          = $user->billing;

            // Set unique id for this order
            $uid                   = uid();

            // Get buyer id
            $buyer_id              = $user->id;

            // Save order
            $order                 = new Order();
            $order->uid            = $uid;
            $order->buyer_id       = $buyer_id;
            $order->total_value    = $total;
            $order->subtotal_value = $subtotal;
            $order->taxes_value    = $tax;
            $order->save();

            // Loop through items in cart
            foreach ($cart as $key => $item) {
                    
                // Get gig
                $gig = Gig::where('uid', $item['id'])->with('owner')->active()->first();

                // Check if gig exists
                if ($gig) {
                    
                    // Set quantity
                    $quantity        = isset($item['quantity']) ? convertToNumber($item['quantity']) : 1;

                    // Set gig upgrades
                    $upgrades        = isset($item['upgrades']) && is_array($item['upgrades']) && count($item['upgrades']) ? $item['upgrades'] : [];

                    // Set empty variable
                    $upgrades_amount = 0;

                    // Loop through upgrades
                    foreach ($upgrades as $index => $upgrade) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                            
                            $upgrades_amount += convertToNumber($upgrade['price']) * $quantity;

                        }

                    }

                    // Set item total price
                    $item_total = $upgrades_amount + ( convertToNumber($item['gig']['price']) * $quantity );

                    // Calculate commission first
                    if ($commission_settings->commission_from === 'orders') {
                        
                        // Check commission type
                        if ($commission_settings->commission_type === 'percentage') {
                            
                            // Calculate commission
                            $commission = convertToNumber($commission_settings->commission_value) * $item_total / 100;
    
                        } else {
    
                            // Fixed amount
                            $commission = convertToNumber($commission_settings->commission_value);
    
                        }

                    } else {
                        
                        // No commission
                        $commission = 0;

                    }

                    // Save order item
                    $order_item                         = new OrderItem();
                    $order_item->uid                    = uid();
                    $order_item->order_id               = $order->id;
                    $order_item->gig_id                 = $gig->id;
                    $order_item->owner_id               = $gig->user_id;
                    $order_item->quantity               = $quantity;
                    $order_item->has_upgrades           = count($upgrades) ? true : false;
                    $order_item->total_value            = $item_total;
                    $order_item->profit_value           = $item_total - $commission;
                    $order_item->commission_value       = $commission;
                    $order_item->save();

                    // Loop through upgrades again
                    foreach ($upgrades as $index => $value) {
                        
                        // Check if upgrade is selected
                        if ( isset($upgrade['checked']) && $upgrade['checked'] == 1 ) {
                        
                            // Get upgrade
                            $upgrade = GigUpgrade::where('uid', $value['id'])->where('gig_id', $gig->id)->first();
    
                            // Check if upgrade exists
                            if ($upgrade) {
                                
                                // Save item upgrade
                                $order_item_upgrade             = new OrderItemUpgrade();
                                $order_item_upgrade->item_id    = $order_item->id;
                                $order_item_upgrade->title      = $upgrade->title;
                                $order_item_upgrade->price      = $upgrade->price;
                                $order_item_upgrade->extra_days = $upgrade->extra_days;
                                $order_item_upgrade->save();
    
                            }

                        }
                        
                    }

                    // Update seller pending balance
                    $gig->owner()->update([
                        'balance_pending' => convertToNumber($gig->owner->balance_pending) + convertToNumber($order_item->profit_value)
                    ]);

                    // Increment orders in queue
                    $gig->increment('orders_in_queue');

                    // Order item placed successfully
                    // Let's notify the seller about new order
                    $gig->owner->notify( (new PendingOrder($order_item))->locale(config('app.locale')) );

                    // Check user's level
                    check_user_level($buyer_id);

                    // Send notification
                    notification([
                        'text'    => 't_u_received_new_order_seller',
                        'action'  => url('seller/orders/details', $order_item->uid),
                        'user_id' => $order_item->owner_id
                    ]);

                }

            }

            // Save invoice
            $invoice                 = new OrderInvoice();
            $invoice->order_id       = $order->id;
            $invoice->payment_method = $this->gateway;
            $invoice->payment_id     = $payment_id;
            $invoice->firstname      = $billing_info->firstname ?? $user->username;
            $invoice->lastname       = $billing_info->lastname ?? $user->username;
            $invoice->email          = $user->email;
            $invoice->company        = !empty($billing_info->company) ? clean($billing_info->company) : null;
            $invoice->address        = !empty($billing_info->address) ? clean($billing_info->address) : "NA";
            $invoice->status         = 'paid';
            $invoice->save();

            // Update balance
            $user->update([
                'balance_purchases' => convertToNumber($user->balance_purchases) + convertToNumber($total)
            ]);

            // Now everything succeeded
            // Let's empty the cart
            session()->forget('cart');

            // Now let's notify the buyer that his order has been placed
            $user->notify( (new OrderPlaced($order, $total))->locale(config('app.locale')) );

            //check for affiliate registeration and check if expired 
            if(settings('affiliate')->is_enabled)
            {
            $affiliate_register =AffiliateRegisteration::where('user_id', $buyer_id)
                                                        ->where('expires_at','>',now())
                                                        ->first() ;
            if($affiliate_register){
                
                // get referral user
                $referral_user = User::where('id', $affiliate_register->referral_id)->first();
                
                // calculate referral earning
                $referral_earning =(convertToNumber(settings('affiliate')->profit_percentage)/100)*convertToNumber($total);
                   
                // add credit to referral wallet
                $referral_balance = convertToNumber($referral_user->balance_available) + $referral_earning;
                $referral_user->update(['balance_available'=>$referral_balance]);

                // create new affiliate transaction
                $affiliate_transaction = new AffiliateTransaction();
                $affiliate_transaction->user_id = $buyer_id ;
                $affiliate_transaction->referral_id = $referral_user->id ;
                $affiliate_transaction->order_id = $order->id ;
                $affiliate_transaction->referral_earning = $referral_earning ;
                $affiliate_transaction->save();
            }
            }


        } catch (\Throwable $th) {
            
            // Error
            throw $th;

        }
    }


    /**
     * Calculate fee value
     *
     * @param string $type
     * @param mixed $amount
     * @return mixed
     */
    private function fee($type, $amount = null)
    {
        try {
            
            // Set amount for deposit
            $amount = convertToNumber($amount) * $this->settings?->exchange_rate / settings('currency')->exchange_rate;

            // Remove long decimal
            $amount = convertToNumber( number_format($amount, 2, '.', '') );

            // Check fee type
            switch ($type) {
    
                // Deposit
                case 'deposit':
    
                    // Get deposit fixed fee
                    if (isset($this->settings->fixed_fee['deposit'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['deposit']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get deposit percentage fee
                    if (isset($this->settings->percentage_fee['deposit'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['deposit']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
                    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
                    
                    // Return fee value
                    return number_format($fee_value, 2, '.', '');
    
                break;

                // Gigs
                case 'gigs':

                    // Get gigs fixed fee
                    if (isset($this->settings->fixed_fee['gigs'])) {
                        
                        // Set fixed fee
                        $fee_fixed = convertToNumber($this->settings->fixed_fee['gigs']);
    
                    } else {
    
                        // No fixed fee
                        $fee_fixed = 0;
    
                    }
    
                    // Get gigs percentage fee
                    if (isset($this->settings->percentage_fee['gigs'])) {
                        
                        // Set percentage fee
                        $fee_percentage = convertToNumber($this->settings->percentage_fee['gigs']);
    
                    } else {
    
                        // No percentage fee
                        $fee_percentage = 0;
    
                    }
    
                    // Calculate percentage of this amount 
                    $fee_percentage_amount = $this->exchange( $fee_percentage * $amount / 100, $this->settings->exchange_rate );

                    // Calculate exchange rate of this fixed fee
                    $fee_fixed_exchange    = $this->exchange( $fee_fixed,  $this->settings->exchange_rate);
    
                    // Calculate fee value and visible text
                    if ($fee_fixed > 0 && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount) + convertToNumber($fee_fixed_exchange);
    
                    } else if (!$fee_fixed && $fee_percentage > 0) {
                        
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_percentage_amount);
    
                    } else if ($fee_fixed > 0 && !$fee_percentage) {
    
                        // Calculate fee value
                        $fee_value = convertToNumber($fee_fixed_exchange);
                        
                    } else if (!$fee_percentage && !$fee_fixed) {
                        
                        // Calculate fee value
                        $fee_value = 0;
    
                    }
    
                    // Return fee value
                    return $fee_value;

                break;
    
            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return 0;

        }
    }


    /**
     * Calculate exchange rate
     *
     * @param mixed $amount
     * @param mixed $exchange_rate
     * @param boolean $formatted
     * @param string $currency
     * @return mixed
     */
    private function exchange($amount, $exchange_rate, $formatted = false, $currency = null)
    {
        try {

            // Convert amount to number
            $amount                = convertToNumber($amount);

            // Get currency settings
            $currency_settings     = settings('currency');

            // Get default currency exchange rate
            $default_exchange_rate = convertToNumber($currency_settings->exchange_rate);

            // Get exchanged amount
            $exchanged_amount      = convertToNumber( $amount *  $default_exchange_rate / $exchange_rate );

            // Check if we have to return a formatted value
            if ($formatted) {
                
                return money( $exchanged_amount, $currency, true )->format();

            }

            // Return max deposit
            return convertToNumber(number_format( $exchanged_amount, 2, '.', '' ));

        } catch (\Throwable $th) {

            // Something went wrong
            return $amount;

        }
    }


    /**
     * Send a notification to user
     *
     * @param string $type
     * @param object $user
     * @return void
     */
    private function notification($type, $user)
    {
        try {
            
            // Check notification type
            switch ($type) {

                // Deposit funds
                case 'deposit':
                    


                break;

                // Gig checkout
                case 'gig':
                    
                    

                break;

                // Project payment
                case 'project':
                    
                    

                break;

                // Bid payment
                case 'bid':
                    
                    

                break;

            }

        } catch (\Throwable $th) {
            
            // Something went wrong
            return;

        }
    }


    /**
     * Redirecting
     *
     * @param string $type
     * @param string $status
     * @return void
     */
    private function redirect($type, $status = 'success')
    {
        // Check where to redirect
        switch ($type) {

            // Deposit history
            case 'deposit':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_ur_transaction_has_completed'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/deposit/history')->with('success', __('messages.t_mollie_payment_pending'));

                }
                

            break;

            // Gigs order
            case 'gigs':
                
                // Check if payment succeeded
                if ($status === 'success') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_submit_ur_info_now_seller_start_order'));

                } else if ($status === 'pending') {
                    
                    // Redirect to deposit history page
                    return redirect('account/orders')->with('success', __('messages.t_mollie_payment_pending'));

                }

            break;

        }
    }
}
<!DOCTYPE html>
<html>

<head>
    <style id="grid1">
        * {
          box-sizing: border-box;
        }
        .wrapper {
          max-width: 940px;
          margin: 0 auto;
        }
        
        .wrapper > div {
          border: 2px solid rgb(233 171 88);
          border-radius: 5px;
          background-color: rgb(233 171 88 / 50%);
          padding: 1em;
          color: #d9480f;
        }
        
        .wrapper {
          display: grid;
          grid-template-columns: repeat(3, 5fr);
          gap: 10px;
          grid-auto-rows: minmax(100px, auto);
        }
        .one {
          grid-column: 1 / 3;
          grid-row: 1;
        }
        .two {
          grid-column: 3 ;
          grid-row: 1 / 4;
        }
        .three {
          grid-column: 1;
          grid-row: 2 / 5;
        }
        .four {
          grid-column: 2;
          grid-row: 2 / 4;
        }
        .five {
          grid-column: 2;
          grid-row: 4;
        }
        .six {
          grid-column: 3;
          grid-row: 4;
        }
    </style>
    <style id="grid2">
    .item1 { grid-area: header; }
    .item2 { grid-area: menu; }
    .item3 { grid-area: main; }
    .item4 { grid-area: right; }
    .item5 { grid-area: footer; }

    .grid-container {
      display: grid;
      grid-template-areas:
        'header header header header header header'
        'menu main main main right right'
        'menu footer footer footer footer footer';
      gap: 10px;
      background-color: #2196F3;
      padding: 10px;
    }

    .grid-container > div {
      background-color: rgba(255, 255, 255, 0.8);
      text-align: center;
      padding: 20px 0;
      font-size: 30px;
    }
    </style>
</head>

<body>
    <div class="wrapper" id="grid1">
        <div class="one">One</div>
        <div class="two">Two</div>
        <div class="three">Three</div>
        <div class="four">Four</div>
        <div class="five">Five</div>
        <div class="six">Six</div>
    </div>
    <div class="grid-container" id="grid2">
        <div class="item1">Header</div>
        <div class="item2">Menu</div>
        <div class="item3">Main</div>  
        <div class="item4">Right</div>
        <div class="item5">Footer</div>
	</div>

</body>

</html>
i am learning javascript, i created a program to add two number using function
{
  "orgName": "Demo company",
  "edition": "Developer",
  "features": []
}
{
  "orgName": "Demo company",
  "edition": "Developer",
  "features": []
}
// Check to see if running in a Console
    var workspaceAPI = component.find("workspace");
    workspaceAPI.isConsoleNavigation().then(function(consoleResponse) {            
        console.log("IsConsole: ", consoleResponse);
        if (consoleResponse) {

            // Save current tab info
            workspaceAPI.getFocusedTabInfo().then(function(tabResponse) {
                var closeTabId = tabResponse.tabId;
                var closeTitle = tabResponse.title;
                var parentTabId = tabResponse.parentTabId;
                var isSubtab = tabResponse.isSubtab;
                console.log("Current Tab: ", closeTabId + " | " + closeTitle);
                console.log("Is Sub: ",isSubtab," ParentId: ",parentTabId);

                // Open Visualforce Page in a new tab
                if (isSubtab) {
                    workspaceAPI.openSubtab({
                        parentTabId: parentTabId,
                        url: vfURL,
                        focus: true
                    }).then(function(openSubResponse) {
                        console.log("New SubTab Id: ", openSubResponse);
                    })
                    .catch(function(error) {
                        console.log(error);
                    });                        
                } else {
                    workspaceAPI.openTab({
                        url: vfURL,
                        focus: true
                    }).then(function(openParResponse) {
                        console.log("New ParentTab Id: ", openParResponse);
                    })
                    .catch(function(error) {
                        console.log(error);
                    });                        
                }

                // Because exiting the VF page will reopen the object record,
                // close the tab we started on
                if (tabResponse.closeable && !tabResponse.pinned) {
                    workspaceAPI.closeTab({
                        tabId: closeTabId
                    }).then(function(closeResponse) {
                        console.log("Closed: ", closeTitle);                      
                    })
                    .catch(function(error) {
                        console.log(error);
                    });                            
                } else {
                    console.log("Left Open: ", tabResponse.title);
                }
            })
            .catch(function(error) {
                console.log(error);
            })
                // Handle non-console user
                console.log("Not in Console");
                var urlEvent = $A.get("e.force:navigateToURL");
                urlEvent.setParams({
                     "url": vfURL
                });
                urlEvent.fire();
    doInit : function(component, event, helper) {
        var params = new Array();
        params.push(component.get('v.recordIdVar') + '=' + component.get('v.recordId'));
        params.push(component.get('v.otherParams'));
        component.set('v.queryString', params.join('&'))
    },

    openPage : function(component, event, helper) {

        // Show spinner once button is pressed
        var spinner = component.find('spinner');
        $A.util.removeClass(spinner, 'slds-hide');

        // Build url for Visualforce page
        var vfURL = 'https://' + component.get("v.domain") + '--c.visualforce.com/apex/';
        vfURL = vfURL + component.get("v.pageName") + '?';
        vfURL = vfURL + component.get("v.queryString");
        console.log("VF URL: ",vfURL);
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">

    <lightning:workspaceAPI aura:id="workspace" />

    <aura:attribute name="buttonLabel" type="String" />
    <aura:attribute name="buttonVariant" type="String" default="neutral" />
    <aura:attribute name="domain" type="String" />
    <aura:attribute name="pageName" type="String" />
    <aura:attribute name="recordIdVar" type="String" />
    <aura:attribute name="otherParams" type="String" />

    <aura:attribute name="queryString" type="String" />

    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <lightning:card>
        <lightning:layoutItem padding="around-small">
            <lightning:button label="{!v.buttonLabel}" variant="{!v.buttonVariant}" onclick="{!c.openPage}" />
            <lightning:spinner aura:id="spinner" alternativeText="Loading" variant="brand" size="large" class="slds-hide" />
        </lightning:layoutItem>
    </lightning:card>

</aura:component>
Creating an audit trail in SQL involves capturing and recording changes made to the data in a database, along with metadata like who made the change, when it was made, and what the original and new values were. Here are some common methods to create an audit trail in SQL:

### 1. *Using Triggers*
Triggers are a common way to create an audit trail in SQL. A trigger can be set up to fire before or after an INSERT, UPDATE, or DELETE operation. The trigger then logs the changes into an audit table.

#### Example:
Suppose you have a table named employees and you want to audit changes.

1. *Create an Audit Table:*
    sql
    CREATE TABLE employees_audit (
        audit_id INT AUTO_INCREMENT PRIMARY KEY,
        employee_id INT,
        action VARCHAR(10),
        old_value VARCHAR(255),
        new_value VARCHAR(255),
        changed_by VARCHAR(50),
        changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    

2. **Create a Trigger for UPDATE:**
    sql
    CREATE TRIGGER employees_update_audit
    AFTER UPDATE ON employees
    FOR EACH ROW
    BEGIN
        INSERT INTO employees_audit (employee_id, action, old_value, new_value, changed_by)
        VALUES (
            OLD.employee_id, 
            'UPDATE', 
            OLD.salary, 
            NEW.salary, 
            USER()
        );
    END;
    

This trigger captures changes made to the salary column and stores the old and new values, the action performed, who performed the action, and when.

3. **Create Triggers for INSERT and DELETE:**
    Similar triggers can be created for INSERT and DELETE operations.

### 2. *Change Data Capture (CDC)*
If your database supports Change Data Capture (CDC), you can enable this feature to automatically track changes without creating manual triggers.

- *SQL Server Example:*
    sql
    EXEC sys.sp_cdc_enable_table 
        @source_schema = 'dbo', 
        @source_name = 'employees', 
        @role_name = NULL;
    

- *Oracle Example:*
    Oracle has its own built-in auditing features that can be configured via DBMS packages or directly using the AUDIT command.

### 3. *Manual Logging*
If you want to avoid using triggers, you can manually log changes by writing data into an audit table within your SQL operations.

#### Example:
sql
UPDATE employees 
SET salary = 60000 
WHERE employee_id = 101;

INSERT INTO employees_audit (employee_id, action, old_value, new_value, changed_by)
VALUES (101, 'UPDATE', '50000', '60000', 'admin');


### 4. *Temporal Tables*
Some databases like SQL Server 2016+ support temporal tables, which automatically keep track of historical data. You can enable a table to be temporal, and SQL Server will automatically manage the history.

#### Example:
sql
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    salary INT,
    SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START,
    SysEndTime DATETIME2 GENERATED ALWAYS AS ROW END,
    PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
) WITH (SYSTEM_VERSIONING = ON);


### Best Practices:
- *Minimal Performance Impact:* Triggers can introduce performance overhead, so ensure they're optimized and only track necessary data.
- *Data Integrity:* Ensure that the audit trail can't be easily tampered with by using appropriate permissions.
- *Compliance:* Ensure that your audit trail complies with legal and regulatory requirements for data retention and privacy.

By implementing one or more of these methods, you can effectively create an audit trail in SQL to track changes in your database.
const animals = ['hippo', 'tiger', 'lion', 'seal', 'cheetah', 'monkey', 'salamander', 'elephant'];

const foundAnimal = animals.findIndex(a => {
  return a === 'elephant';
});
console.log(animals[foundAnimal]); // uses function's returned index to display value

const startsWithS = animals.findIndex(letter => {
  return letter[0] === 's';
});
console.log(startsWithS); // function returns index number of first TRUE element
console.log(animals[startsWithS]); // used to display that element's value
Select id, name, Parent__r.name, Parent__r.id from Child__c
 
Select id, name, Parent__r.name,(SELECT id, name, amount__c FROM Children__r) from Parent__c
const favoriteWords = ['nostalgia', 'hyperbole', 'fervent', 'esoteric', 'serene'];

// Call .filter() on favoriteWords below

const longFavoriteWords = favoriteWords.filter(word => {
  return word.length > 7;
});

console.log(longFavoriteWords);
 const searchParams = new URLSearchParams(window.location.search);
  const id = searchParams.get('id');
  console.log(id)
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
<html>	
   
   <input id="contact" name="address">
 
 <script>
 
    document.getElementById("contact").attribute = "phone";
	
    //ALTERNATIVE METHOD TO CHANGE
    document.getElementById("contact").setAttribute('name', 'phone');	
 
  </script>
 
</html>
{
	"blocks": [
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": ":star: What's on in Melbourne this week! :star:"
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n\n Hey Melbourne, happy Monday! Please see below for what's on this week! "
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": "Xero Café :coffee:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n :new-thing: This week we are offering some *Arnott's Classics!* \n\n We have Gluten Free Scotch Fingers, Hundreds and Thousands Biscuits & Monte Carlo Biscuits!\n\n *Weekly Café Special*: _Hazelnut Latte_"
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": " Wednesday, 21st August :calendar-date-21:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "\n\n:late-cake: *Afternoon Tea*: From *2pm* in the *L1, L2 and L3* kitchens! Check out the menu in the thread! :thread: \n:massage:*Wellbeing - Massage*: Book a session <https://bookings.corporatebodies.com/|*here*> to relax and unwind. \n *Username:* xero \n *Password:* 1234"
			}
		},
		{
			"type": "header",
			"text": {
				"type": "plain_text",
				"text": " Thursday, 22nd August :calendar-date-22:",
				"emoji": true
			}
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": ":breakfast: *Breakfast*: Provided by *Kartel Catering* from *8:30am - 10:30am* in the Wominjeka Breakout Space.\n\n :cowboyblob: *Nashville Social:* 4pm - 6pm in the Wominjeka Breakout Space!"
			}
		},
		{
			"type": "divider"
		},
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "Stay tuned to this channel for more details, check out the <https://calendar.google.com/calendar/u/0?cid=Y19xczkyMjk5ZGlsODJzMjA4aGt1b3RnM2t1MEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t|*Melbourne Social Calendar*>, and get ready to Boost your workdays!\n\nLove,\nWX Team :party-wx:"
			}
		}
	]
}
$stripe = new \Stripe\StripeClient('sk_test_51KX5RA...CV00KMzNeBbs
sk_test_51KX5RAHpz0yDkAJjgP65eUwiAJMY1mHeA4LoeX6162wxO6RDyGFZaQR6mOY1X9e7PpVAXkC1AT1HWNfE7ri3HRCV00KMzNeBbs
');
$stripe->customers->update(
  'cus_NffrFeUfNV2Hib',
  ['metadata' => ['order_id' => '6735']]
);
{
  "log": {
    "version": "1.2",
    "creator": {
      "name": "WebInspector",
      "version": "537.36"
    },
    "pages": [],
    "entries": [
      {
        "_initiator": {
          "type": "script",
          "stack": {
            "callFrames": [],
            "parent": {
              "description": "Image",
              "callFrames": [
                {
                  "functionName": "sendEventWithTarget",
                  "scriptId": "10",
                  "url": "https://js.rbxcdn.com/08a545ae1503441b55f5236794feccec.js",
                  "lineNumber": 134,
                  "columnNumber": 130
                },
                {
                  "functionName": "Ml.onInterval",
                  "scriptId": "39",
                  "url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
                  "lineNumber": 7,
                  "columnNumber": 387930
                },
                {
                  "functionName": "Ml.window.Worker.worker.worker.onmessage",
                  "scriptId": "39",
                  "url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
                  "lineNumber": 7,
                  "columnNumber": 388403
                }
              ],
              "parentId": {
                "id": "1",
                "debuggerId": "2503892074991461023.7174108864595547422"
              }
            }
          }
        },
        "_priority": "Low",
        "_resourceType": "image",
        "cache": {},
        "request": {
          "method": "GET",
          "url": "https://ecsv2.roblox.com/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat2&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar&lt=2024-08-09T19%3A37%3A33.374Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73",
          "httpVersion": "h3",
          "headers": [
            {
              "name": ":authority",
              "value": "ecsv2.roblox.com"
            },
            {
              "name": ":method",
              "value": "GET"
            },
            {
              "name": ":path",
              "value": "/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat2&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar&lt=2024-08-09T19%3A37%3A33.374Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73"
            },
            {
              "name": ":scheme",
              "value": "https"
            },
            {
              "name": "accept",
              "value": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
            },
            {
              "name": "accept-encoding",
              "value": "gzip, deflate, br, zstd"
            },
            {
              "name": "accept-language",
              "value": "en-US,en;q=0.9"
            },
            {
              "name": "cookie",
              "value": "GuestData=UserID=-1210413020; RBXSource=rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0; __utmz=200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); .RBXIDCHECK=caebfbee-d232-4825-b7eb-8318f1da9c33; rbxas=fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c; RBXEventTrackerV2=CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004; __utmc=200924205; _ga=GA1.1.781422761.1723013326; .ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1; RBXSessionTracker=sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73; _ga_F8VP9T1NT3=GS1.1.1723218656.3.1.1723218671.0.0.0; rbx-ip2=1; __utma=200924205.337854883.1722793505.1723218657.1723232212.12; __utmb=200924205.0.10.1723232212"
            },
            {
              "name": "priority",
              "value": "i"
            },
            {
              "name": "referer",
              "value": "https://www.roblox.com/"
            },
            {
              "name": "sec-ch-ua",
              "value": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\""
            },
            {
              "name": "sec-ch-ua-mobile",
              "value": "?0"
            },
            {
              "name": "sec-ch-ua-platform",
              "value": "\"Windows\""
            },
            {
              "name": "sec-fetch-dest",
              "value": "image"
            },
            {
              "name": "sec-fetch-mode",
              "value": "no-cors"
            },
            {
              "name": "sec-fetch-site",
              "value": "same-site"
            },
            {
              "name": "user-agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
            }
          ],
          "queryString": [
            {
              "name": "evt",
              "value": "pageHeartbeat_v2"
            },
            {
              "name": "ctx",
              "value": "heartbeat2"
            },
            {
              "name": "url",
              "value": "https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar"
            },
            {
              "name": "lt",
              "value": "2024-08-09T19%3A37%3A33.374Z"
            },
            {
              "name": "gid",
              "value": "-1210413020"
            },
            {
              "name": "sid",
              "value": "2cd50938-0f23-4613-92c1-4e08463a1e73"
            }
          ],
          "cookies": [
            {
              "name": "GuestData",
              "value": "UserID=-1210413020",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-06T14:06:05.665Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "RBXSource",
              "value": "rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-09-03T17:40:28.482Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmz",
              "value": "200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-02-08T07:36:52.000Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": ".RBXIDCHECK",
              "value": "caebfbee-d232-4825-b7eb-8318f1da9c33",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.249Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "rbxas",
              "value": "fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.249Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "RBXEventTrackerV2",
              "value": "CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.688Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmc",
              "value": "200924205",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "1969-12-31T23:59:59.000Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "_ga",
              "value": "GA1.1.781422761.1723013326",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T15:50:57.685Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": ".ROBLOSECURITY",
              "value": "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-12T17:52:14.190Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "RBXSessionTracker",
              "value": "sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T23:36:53.353Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "_ga_F8VP9T1NT3",
              "value": "GS1.1.1723218656.3.1.1723218671.0.0.0",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T15:51:11.309Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "rbx-ip2",
              "value": "1",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T20:36:50.172Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utma",
              "value": "200924205.337854883.1722793505.1723218657.1723232212.12",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T19:36:52.514Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmb",
              "value": "200924205.0.10.1723232212",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T20:06:52.000Z",
              "httpOnly": false,
              "secure": false
            }
          ],
          "headersSize": -1,
          "bodySize": 0
        },
        "response": {
          "status": 200,
          "statusText": "",
          "httpVersion": "h3",
          "headers": [
            {
              "name": "alt-svc",
              "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=259200"
            },
            {
              "name": "content-length",
              "value": "68"
            },
            {
              "name": "content-type",
              "value": "image/png"
            },
            {
              "name": "date",
              "value": "Fri, 09 Aug 2024 19:37:33 GMT"
            },
            {
              "name": "nel",
              "value": "{\"report_to\":\"network-errors\",\"max_age\":604800,\"success_fraction\":0.001,\"failure_fraction\":1}"
            },
            {
              "name": "report-to",
              "value": "{\"group\":\"network-errors\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://ncs.roblox.com/upload\"}]}"
            },
            {
              "name": "server",
              "value": "public-gateway"
            },
            {
              "name": "strict-transport-security",
              "value": "max-age=3600"
            },
            {
              "name": "vary",
              "value": "Origin"
            },
            {
              "name": "x-envoy-upstream-service-time",
              "value": "1"
            },
            {
              "name": "x-ratelimit-limit",
              "value": "3600000, 3600000;w=60, 3600000;w=60"
            },
            {
              "name": "x-ratelimit-remaining",
              "value": "3599995"
            },
            {
              "name": "x-ratelimit-reset",
              "value": "26"
            },
            {
              "name": "x-roblox-edge",
              "value": "bom1"
            },
            {
              "name": "x-roblox-region",
              "value": "us-central_rbx"
            }
          ],
          "cookies": [],
          "content": {
            "size": 68,
            "mimeType": "image/png",
            "text": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=",
            "encoding": "base64"
          },
          "redirectURL": "",
          "headersSize": -1,
          "bodySize": -1,
          "_transferSize": 684,
          "_error": null,
          "_fetchedViaServiceWorker": false
        },
        "serverIPAddress": "128.116.104.4",
        "startedDateTime": "2024-08-09T19:37:33.374Z",
        "time": 320.2770000207238,
        "timings": {
          "blocked": 5.168000029683113,
          "dns": -1,
          "ssl": -1,
          "connect": -1,
          "send": 0.7090000000000001,
          "wait": 311.9660000256076,
          "receive": 2.4339999654330313,
          "_blocked_queueing": 2.022000029683113,
          "_workerStart": -1,
          "_workerReady": -1,
          "_workerFetchStart": -1,
          "_workerRespondWithSettled": -1
        }
      },
      {
        "_initiator": {
          "type": "script",
          "stack": {
            "callFrames": [],
            "parent": {
              "description": "Image",
              "callFrames": [
                {
                  "functionName": "sendEventWithTarget",
                  "scriptId": "10",
                  "url": "https://js.rbxcdn.com/08a545ae1503441b55f5236794feccec.js",
                  "lineNumber": 134,
                  "columnNumber": 130
                },
                {
                  "functionName": "Ml.onInterval",
                  "scriptId": "39",
                  "url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
                  "lineNumber": 7,
                  "columnNumber": 387930
                },
                {
                  "functionName": "Ml.window.Worker.worker.worker.onmessage",
                  "scriptId": "39",
                  "url": "https://js.rbxcdn.com/69f3f6b85c27f2361c01e29eca7868d8d0becfa435bf0173c7b1d11207fe15be.js",
                  "lineNumber": 7,
                  "columnNumber": 388403
                }
              ],
              "parentId": {
                "id": "2",
                "debuggerId": "2503892074991461023.7174108864595547422"
              }
            }
          }
        },
        "_priority": "Low",
        "_resourceType": "image",
        "cache": {},
        "request": {
          "method": "GET",
          "url": "https://ecsv2.roblox.com/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat3&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar&lt=2024-08-09T19%3A37%3A53.393Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73",
          "httpVersion": "h3",
          "headers": [
            {
              "name": ":authority",
              "value": "ecsv2.roblox.com"
            },
            {
              "name": ":method",
              "value": "GET"
            },
            {
              "name": ":path",
              "value": "/www/e.png?evt=pageHeartbeat_v2&ctx=heartbeat3&url=https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar&lt=2024-08-09T19%3A37%3A53.393Z&gid=-1210413020&sid=2cd50938-0f23-4613-92c1-4e08463a1e73"
            },
            {
              "name": ":scheme",
              "value": "https"
            },
            {
              "name": "accept",
              "value": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
            },
            {
              "name": "accept-encoding",
              "value": "gzip, deflate, br, zstd"
            },
            {
              "name": "accept-language",
              "value": "en-US,en;q=0.9"
            },
            {
              "name": "cookie",
              "value": "GuestData=UserID=-1210413020; RBXSource=rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0; __utmz=200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); .RBXIDCHECK=caebfbee-d232-4825-b7eb-8318f1da9c33; rbxas=fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c; RBXEventTrackerV2=CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004; __utmc=200924205; _ga=GA1.1.781422761.1723013326; .ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1; RBXSessionTracker=sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73; _ga_F8VP9T1NT3=GS1.1.1723218656.3.1.1723218671.0.0.0; rbx-ip2=1; __utma=200924205.337854883.1722793505.1723218657.1723232212.12; __utmb=200924205.0.10.1723232212"
            },
            {
              "name": "priority",
              "value": "i"
            },
            {
              "name": "referer",
              "value": "https://www.roblox.com/"
            },
            {
              "name": "sec-ch-ua",
              "value": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\""
            },
            {
              "name": "sec-ch-ua-mobile",
              "value": "?0"
            },
            {
              "name": "sec-ch-ua-platform",
              "value": "\"Windows\""
            },
            {
              "name": "sec-fetch-dest",
              "value": "image"
            },
            {
              "name": "sec-fetch-mode",
              "value": "no-cors"
            },
            {
              "name": "sec-fetch-site",
              "value": "same-site"
            },
            {
              "name": "user-agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
            }
          ],
          "queryString": [
            {
              "name": "evt",
              "value": "pageHeartbeat_v2"
            },
            {
              "name": "ctx",
              "value": "heartbeat3"
            },
            {
              "name": "url",
              "value": "https%3A%2F%2Fwww.roblox.com%2Fmy%2Favatar"
            },
            {
              "name": "lt",
              "value": "2024-08-09T19%3A37%3A53.393Z"
            },
            {
              "name": "gid",
              "value": "-1210413020"
            },
            {
              "name": "sid",
              "value": "2cd50938-0f23-4613-92c1-4e08463a1e73"
            }
          ],
          "cookies": [
            {
              "name": "GuestData",
              "value": "UserID=-1210413020",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-06T14:06:05.665Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "RBXSource",
              "value": "rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-09-03T17:40:28.482Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmz",
              "value": "200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-02-08T07:36:52.000Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": ".RBXIDCHECK",
              "value": "caebfbee-d232-4825-b7eb-8318f1da9c33",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.249Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "rbxas",
              "value": "fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.249Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "RBXEventTrackerV2",
              "value": "CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.688Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmc",
              "value": "200924205",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "1969-12-31T23:59:59.000Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "_ga",
              "value": "GA1.1.781422761.1723013326",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T15:50:57.685Z",
              "httpOnly": false,
              "secure": false	
            },
            {
              "name": ".ROBLOSECURITY",
              "value": "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-12T17:52:14.190Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "RBXSessionTracker",
              "value": "sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T23:36:53.353Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "_ga_F8VP9T1NT3",
              "value": "GS1.1.1723218656.3.1.1723218671.0.0.0",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T15:51:11.309Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "rbx-ip2",
              "value": "1",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T20:36:50.172Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utma",
              "value": "200924205.337854883.1722793505.1723218657.1723232212.12",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T19:36:52.514Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmb",
              "value": "200924205.0.10.1723232212",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T20:06:52.000Z",
              "httpOnly": false,
              "secure": false
            }
          ],
          "headersSize": -1,
          "bodySize": 0
        },
        "response": {
          "status": 200,
          "statusText": "",
          "httpVersion": "h3",
          "headers": [
            {
              "name": "alt-svc",
              "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=259200"
            },
            {
              "name": "content-length",
              "value": "68"
            },
            {
              "name": "content-type",
              "value": "image/png"
            },
            {
              "name": "date",
              "value": "Fri, 09 Aug 2024 19:37:54 GMT"
            },
            {
              "name": "nel",
              "value": "{\"report_to\":\"network-errors\",\"max_age\":604800,\"success_fraction\":0.001,\"failure_fraction\":1}"
            },
            {
              "name": "report-to",
              "value": "{\"group\":\"network-errors\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://ncs.roblox.com/upload\"}]}"
            },
            {
              "name": "server",
              "value": "public-gateway"
            },
            {
              "name": "strict-transport-security",
              "value": "max-age=3600"
            },
            {
              "name": "vary",
              "value": "Origin"
            },
            {
              "name": "x-envoy-upstream-service-time",
              "value": "2"
            },
            {
              "name": "x-ratelimit-limit",
              "value": "3600000, 3600000;w=60, 3600000;w=60"
            },
            {
              "name": "x-ratelimit-remaining",
              "value": "3599994"
            },
            {
              "name": "x-ratelimit-reset",
              "value": "6"
            },
            {
              "name": "x-roblox-edge",
              "value": "bom1"
            },
            {
              "name": "x-roblox-region",
              "value": "us-central_rbx"
            }
          ],
          "cookies": [],
          "content": {
            "size": 68,
            "mimeType": "image/png",
            "text": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=",
            "encoding": "base64"
          },
          "redirectURL": "",
          "headersSize": -1,
          "bodySize": -1,
          "_transferSize": 683,
          "_error": null,
          "_fetchedViaServiceWorker": false
        },
        "serverIPAddress": "128.116.104.4",
        "startedDateTime": "2024-08-09T19:37:53.399Z",
        "time": 304.0679999976419,
        "timings": {
          "blocked": 7.885000016190111,
          "dns": -1,
          "ssl": -1,
          "connect": -1,
          "send": 0.7570000000000006,
          "wait": 293.70699998886136,
          "receive": 1.7189999925903976,
          "_blocked_queueing": 3.8090000161901116,
          "_workerStart": -1,
          "_workerReady": -1,
          "_workerFetchStart": -1,
          "_workerRespondWithSettled": -1
        }
      },
      {
        "_initiator": {
          "type": "script",
          "stack": {
            "callFrames": [
              {
                "functionName": "",
                "scriptId": "38",
                "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                "lineNumber": 0,
                "columnNumber": 1720
              },
              {
                "functionName": "e.exports",
                "scriptId": "38",
                "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                "lineNumber": 0,
                "columnNumber": 184
              },
              {
                "functionName": "e.exports",
                "scriptId": "38",
                "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                "lineNumber": 0,
                "columnNumber": 4657
              }
            ],
            "parent": {
              "description": "Promise.then",
              "callFrames": [
                {
                  "functionName": "s.request",
                  "scriptId": "38",
                  "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                  "lineNumber": 0,
                  "columnNumber": 3347
                },
                {
                  "functionName": "",
                  "scriptId": "38",
                  "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                  "lineNumber": 0,
                  "columnNumber": 6592
                },
                {
                  "functionName": "",
                  "scriptId": "38",
                  "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                  "lineNumber": 7,
                  "columnNumber": 70477
                }
              ],
              "parent": {
                "description": "Promise.then",
                "callFrames": [
                  {
                    "functionName": "ir",
                    "scriptId": "38",
                    "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                    "lineNumber": 7,
                    "columnNumber": 70453
                  },
                  {
                    "functionName": "ur",
                    "scriptId": "38",
                    "url": "https://js.rbxcdn.com/a42a910df4a1d5c873b335020409d2d586da6222ceb868f5009af93036d385c2.js",
                    "lineNumber": 7,
                    "columnNumber": 70874
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 2964
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 2630
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 2735
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 1671
                  },
                  {
                    "functionName": "h",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 1416
                  },
                  {
                    "functionName": "d",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 2776
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 5442
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 4623
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 4728
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 3664
                  },
                  {
                    "functionName": "b",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 3409
                  },
                  {
                    "functionName": "e.sendPulseAndSetTimeout",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 5315
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 5702
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 4623
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 4728
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 3664
                  },
                  {
                    "functionName": "b",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 3409
                  },
                  {
                    "functionName": "e.onTimeout",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 5589
                  },
                  {
                    "functionName": "",
                    "scriptId": "48",
                    "url": "https://js.rbxcdn.com/d064c41bb0818a1981ea76fac0d1e25142b6117a2197ba92f670612c01ea71f2.js",
                    "lineNumber": 0,
                    "columnNumber": 5502
                  }
                ]
              }
            }
          }
        },
        "_priority": "High",
        "_resourceType": "xhr",
        "cache": {},
        "request": {
          "method": "POST",
          "url": "https://apis.roblox.com/user-heartbeats-api/pulse",
          "httpVersion": "h3",
          "headers": [
            {
              "name": ":authority",
              "value": "apis.roblox.com"
            },
            {
              "name": ":method",
              "value": "POST"
            },
            {
              "name": ":path",
              "value": "/user-heartbeats-api/pulse"
            },
            {
              "name": ":scheme",
              "value": "https"
            },
            {
              "name": "accept",
              "value": "application/json, text/plain, */*"
            },
            {
              "name": "accept-encoding",
              "value": "gzip, deflate, br, zstd"
            },
            {
              "name": "accept-language",
              "value": "en-US,en;q=0.9"
            },
            {
              "name": "content-length",
              "value": "199"
            },
            {
              "name": "content-type",
              "value": "application/json;charset=UTF-8"
            },
            {
              "name": "cookie",
              "value": "GuestData=UserID=-1210413020; RBXSource=rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0; __utmz=200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); .RBXIDCHECK=caebfbee-d232-4825-b7eb-8318f1da9c33; rbxas=fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c; RBXEventTrackerV2=CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004; __utmc=200924205; _ga=GA1.1.781422761.1723013326; .ROBLOSECURITY=_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1; RBXSessionTracker=sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73; _ga_F8VP9T1NT3=GS1.1.1723218656.3.1.1723218671.0.0.0; rbx-ip2=1; __utma=200924205.337854883.1722793505.1723218657.1723232212.12; __utmb=200924205.0.10.1723232212"
            },
            {
              "name": "origin",
              "value": "https://www.roblox.com"
            },
            {
              "name": "priority",
              "value": "u=1, i"
            },
            {
              "name": "referer",
              "value": "https://www.roblox.com/"
            },
            {
              "name": "sec-ch-ua",
              "value": "\"Not)A;Brand\";v=\"99\", \"Google Chrome\";v=\"127\", \"Chromium\";v=\"127\""
            },
            {
              "name": "sec-ch-ua-mobile",
              "value": "?0"
            },
            {
              "name": "sec-ch-ua-platform",
              "value": "\"Windows\""
            },
            {
              "name": "sec-fetch-dest",
              "value": "empty"
            },
            {
              "name": "sec-fetch-mode",
              "value": "cors"
            },
            {
              "name": "sec-fetch-site",
              "value": "same-site"
            },
            {
              "name": "user-agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
            },
            {
              "name": "x-bound-auth-token",
              "value": "acOOtUInHmBzbl9fpgOXX04Ns2j4OUgzhgUHQtQzrkI=|1723232274|TuRJw65L9TpuHDsbcMIwAWhyL6LyA9DqaE6tVeiRFkRdfdw12jhwImWUAp1lVcT1qzBChlF6gJH3sV0Drwlqyw=="
            },
            {
              "name": "x-csrf-token",
              "value": "Rjm15WXsfrx8"
            }
          ],
          "queryString": [],
          "cookies": [
            {
              "name": "GuestData",
              "value": "UserID=-1210413020",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-06T14:06:05.665Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "RBXSource",
              "value": "rbx_acquisition_time=08/04/2024 17:40:28&rbx_acquisition_referrer=&rbx_medium=Social&rbx_source=&rbx_campaign=&rbx_adgroup=&rbx_keyword=&rbx_matchtype=&rbx_send_info=0",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-09-03T17:40:28.482Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmz",
              "value": "200924205.1722793505.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-02-08T07:36:52.000Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": ".RBXIDCHECK",
              "value": "caebfbee-d232-4825-b7eb-8318f1da9c33",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.249Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "rbxas",
              "value": "fb39906bfdc34fdf16f4c815f48b18a791df8dffd4a2d419ae03332669d9432c",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.249Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "RBXEventTrackerV2",
              "value": "CreateDate=08/04/2024 12:46:11&rbxid=1525895574&browserid=1722607566239004",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-08T17:46:10.688Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmc",
              "value": "200924205",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "1969-12-31T23:59:59.000Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "_ga",
              "value": "GA1.1.781422761.1723013326",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T15:50:57.685Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": ".ROBLOSECURITY",
              "value": "_|WARNING:-DO-NOT-SHARE-THIS.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items.|_D12C786F9BC5858284B5622D28449D7EC2598C5666BA0CDB504D72B45B9E5F1B4784C54A03EC1B28371C8DCD3363D724B4E3E7826ABD5E643A9B985A4B967BFEEA9C02EC89ADE3489B3C81BD1F92E8D81C0D8461C6DBE8CEE693E7C98302DD329569F63CCD934F5E158869DCFE23F56D32FEC3CF4BC6D366A25C1154911DEFE551EA6EA59D3792F4C35EB99C4BDC20E20EFF992E4D0CD414324B39FE35F079586068C40E192678F1002A87A6FDF9EFD7710618ABEC907FDF973FE488A6E29C3ECC99E5C28587BB17D7BFC7D9B208D87887EEFB5876CD8F86DFCF8F07CA6CABAF62767BF90F1578345B87478C1C9A15F6A389DD4FCB286B6DE9FD8CCFF5FE26A588E37027B0C1460F1BCE329C68F36DB322D1B0AEB187538B687971B802CC2D04F47ACF86AF0A07C3D538FB715107213FAFE2CDF578AFA52E8581753B1F1E176E50E74FDA2514CC4E9CEFA4D4DAB5DF90BCC5D27A0813387FE84C1E6AD236E2A4C01E3A87065FB397F2577A71B881BA837275B0F819347F1ED3FC7B177334DD2E855D06D4E89FF02CF059F538B6D820A318845DB2FB32FA7DA47ADA545C0A33B1AD24CDCDF22F725AD06C95D83E96F66A7403BA787D8A79969F002B0C98F24260E3A889B430504E19C1A3B81B5B08ED80C2EE676760D726612ABBA2E42EC0AEE8252862CA36553DACF10BD9C4D9106301983EA41B203C562FB92812EE59BADCCA48E847E01510C6E1813853E3BE3F39F7CBBCF28C6FFC4EE150E10DCE787043C0C7C36613B72AF05A708CF1AD4A4CB387F0CA0A1C12E7FEFA902D13724F10C11310D64BC86176573D10846B47E726B792EB287917DA2525F8856F9476C214EBD2E9AAAE34B29EF51172A15A782767FE7277F7B8E9CEEAEECBC3CBDC2F536463FB21C0C4CC7F63F4D686C1C687BEDB568A779BF8C33940CE87BF4AD88DBE4F42C27E24AADFEB754DE8FE2698AD55EF111A1663ADAC9A23B653F81B99F486788710A28052081D606E98A62E139F66B07ADF9423839800A5906A34BE8A627C7DDD9381805A70466FA5D07914EB453C4A96121AFBC6B1",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-12T17:52:14.190Z",
              "httpOnly": true,
              "secure": true
            },
            {
              "name": "RBXSessionTracker",
              "value": "sessionid=2cd50938-0f23-4613-92c1-4e08463a1e73",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T23:36:53.353Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "_ga_F8VP9T1NT3",
              "value": "GS1.1.1723218656.3.1.1723218671.0.0.0",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T15:51:11.309Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "rbx-ip2",
              "value": "1",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T20:36:50.172Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utma",
              "value": "200924205.337854883.1722793505.1723218657.1723232212.12",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2025-09-13T19:36:52.514Z",
              "httpOnly": false,
              "secure": false
            },
            {
              "name": "__utmb",
              "value": "200924205.0.10.1723232212",
              "path": "/",
              "domain": ".roblox.com",
              "expires": "2024-08-09T20:06:52.000Z",
              "httpOnly": false,
              "secure": false
            }
          ],
          "headersSize": -1,
          "bodySize": 199,
          "postData": {
            "mimeType": "application/json;charset=UTF-8",
            "text": "{\"clientSideTimestampEpochMs\":1723232274741,\"sessionInfo\":{\"sessionId\":\"2cd50938-0f23-4613-92c1-4e08463a1e73\"},\"locationInfo\":{\"robloxWebsiteLocationInfo\":{\"url\":\"https://www.roblox.com/my/avatar\"}}}"
          }
        },
        "response": {
          "status": 200,
          "statusText": "",
          "httpVersion": "h3",
          "headers": [
            {
              "name": "access-control-allow-credentials",
              "value": "true"
            },
            {
              "name": "access-control-allow-origin",
              "value": "https://www.roblox.com"
            },
            {
              "name": "alt-svc",
              "value": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=259200"
            },
            {
              "name": "content-type",
              "value": "application/json; charset=utf-8"
            },
            {
              "name": "date",
              "value": "Fri, 09 Aug 2024 19:37:55 GMT"
            },
            {
              "name": "nel",
              "value": "{\"report_to\":\"network-errors\",\"max_age\":604800,\"success_fraction\":0.001,\"failure_fraction\":1}"
            },
            {
              "name": "report-to",
              "value": "{\"group\":\"network-errors\",\"max_age\":604800,\"endpoints\":[{\"url\":\"https://ncs.roblox.com/upload\"}]}"
            },
            {
              "name": "server",
              "value": "public-gateway"
            },
            {
              "name": "strict-transport-security",
              "value": "max-age=3600"
            },
            {
              "name": "vary",
              "value": "Origin"
            },
            {
              "name": "x-envoy-upstream-service-time",
              "value": "2"
            },
            {
              "name": "x-roblox-edge",
              "value": "bom1"
            },
            {
              "name": "x-roblox-region",
              "value": "us-central_rbx"
            }
          ],
          "cookies": [],
          "content": {
            "size": 78,
            "mimeType": "application/json",
            "text": "{\"sessionId\":\"2cd50938-0f23-4613-92c1-4e08463a1e73\",\"status\":200,\"message\":\"\"}"
          },
          "redirectURL": "",
          "headersSize": -1,
          "bodySize": -1,
          "_transferSize": 680,
          "_error": null,
          "_fetchedViaServiceWorker": false
        },
        "serverIPAddress": "128.116.104.4",
        "startedDateTime": "2024-08-09T19:37:54.757Z",
        "time": 314.01399994501844,
        "timings": {
          "blocked": 8.659999978940935,
          "dns": -1,
          "ssl": -1,
          "connect": -1,
          "send": 1.689,
          "wait": 301.7659999998622,
          "receive": 1.8989999662153423,
          "_blocked_queueing": 3.612999978940934,
          "_workerStart": -1,
          "_workerReady": -1,
          "_workerFetchStart": -1,
          "_workerRespondWithSettled": -1
        }
      }
    ]
  }
}
public function rules()
  {
    return [

      [['id_ente', 'id_estado', 'id_aeropuerto', 'id_linea', 'id_indicador', 'id_concep', 'pasajeros_transportados_n', 'pasajeros_transportados_i', 'cantidad_aeronaves_operativas_n', 'cantidad_aeronaves_operativas_i', 'cantidad_aeronaves_recuperadas_n', 'cantidad_aeronaves_recuperadas_i', 'cantidad_aeronaves_recuperar_n', 'cantidad_aeronaves_necesarias_n', 'cantidad_aeronaves_necesarias_i', 'cantidad_aeronaves_operativas_ci', 'cantidad_aeronaves_operativas_cn', 'numero_operaciones_vu', 'id_municipio', 'id_parroquia','id_plazo_ae', 'id_tip_trans_ae', 'id_tip_inve_ae', 'id_estatus_obra'], 'integer'],
      [['vuelo', 'uso', 'moneda'], 'string'],
      [['monto', 'cantidad_aeronaves_recuperar_i'], 'number', 'min' => 0],
      [['fecha', 'carga_transportada_i', 'carga_transportada_n'], 'safe'],
      [['nombre_proyecto'], 'string', 'max' => 250],
      [['descripcion'], 'string', 'max' => 250],
      [['id_municipio'], 'exist', 'skipOnError' => true, 'targetClass' => Municipios::className(), 'targetAttribute' => ['id_municipio' => 'id_municipio']],
      [['id_parroquia'], 'exist', 'skipOnError' => true, 'targetClass' => Parroquias::className(), 'targetAttribute' => ['id_parroquia' => 'id_parroquia']],
      [['id_tip_trans_ae'], 'exist', 'skipOnError' => true, 'targetClass' => TipoTransporteAe::className(), 'targetAttribute' => ['id_tip_trans_ae' => 'id_tip_trans_ae']],
      [['id_tip_inve_ae'], 'exist', 'skipOnError' => true, 'targetClass' => TiposInversiones::className(), 'targetAttribute' => ['id_tip_inve_ae' => 'id_tip_inve']],
      [['fecha'], 'required'],
    ];
  }
<div style="flex: 1 0 100%; display: block;" id='carga_transportada_i'>
                                            <?= $form->field($model, 'carga_transportada_i')->widget(MaskedInput::className(), [
                                        'clientOptions' => [
                                            'alias' => 'decimal',
                                            'groupSeparator' => '.',
                                            'radixPoint' => ',',
                                            'autoGroup' => true,
                                            'digits' => 2,
                                            'digitsOptional' => false,
                                            'allowMinus' => false,
                                            'rightAlign' => false
                                        ],
                                        'options' => [
                                            'class' => 'form-control',
                                            //'placeholder' => '600 (Número entero)',
                                            //'maxlength' => 10
                                        ]
                                        ]) ?>
                                        </div>
  
 <?= $form->field($model, 'carga_transportada_n')->widget(MaskedInput::className(), [

                                                'clientOptions' => [
                                                    'alias' => 'decimal',
                                                    'groupSeparator' => '.',
                                                    'radixPoint' => ',',
                                                    'autoGroup' => true,
                                                    'digits' => 2,
                                                    'digitsOptional' => false,
                                                    'allowMinus' => false,
                                                    'rightAlign' => false
                                                ],
                                                'options' => [
                                                    'class' => 'form-control campo-suma',
                                                    //'placeholder' => '600 (Número entero)',
                                                    //'maxlength' => 10
                                                ]

                                            ]) ?>
star

Sat Aug 17 2024 08:42:19 GMT+0000 (Coordinated Universal Time) https://github.com/marketplace/actions/run-ssh-command

@acassell

star

Sat Aug 17 2024 08:41:49 GMT+0000 (Coordinated Universal Time) https://github.com/marketplace/actions/fork-sync

@acassell

star

Sat Aug 17 2024 08:41:16 GMT+0000 (Coordinated Universal Time) https://github.com/marketplace/actions/labeler

@acassell

star

Sat Aug 17 2024 08:39:39 GMT+0000 (Coordinated Universal Time) https://github.com/marketplace/actions/setup-php-action

@acassell

star

Sat Aug 17 2024 08:12:59 GMT+0000 (Coordinated Universal Time) https://github.com/mriscoc/Ender3V2S1/discussions/1092

@amccall23

star

Sat Aug 17 2024 08:12:56 GMT+0000 (Coordinated Universal Time) https://github.com/mriscoc/Ender3V2S1/discussions/1092

@amccall23

star

Sat Aug 17 2024 08:11:54 GMT+0000 (Coordinated Universal Time) https://github.com/actions/setup-node

@acassell

star

Sat Aug 17 2024 08:05:53 GMT+0000 (Coordinated Universal Time) https://docs.github.com/en/actions/use-cases-and-examples/deploying/deploying-nodejs-to-azure-app-service

@acassell

star

Sat Aug 17 2024 08:04:57 GMT+0000 (Coordinated Universal Time) https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-python

@acassell

star

Sat Aug 17 2024 02:53:19 GMT+0000 (Coordinated Universal Time) https://uiverse.io/andrew-demchenk0/stupid-emu-68

@SebasOfEek #css

star

Sat Aug 17 2024 02:52:50 GMT+0000 (Coordinated Universal Time) https://uiverse.io/andrew-demchenk0/bad-squid-34

@SebasOfEek #css

star

Sat Aug 17 2024 02:46:58 GMT+0000 (Coordinated Universal Time) https://uiverse.io/akshat-patel28/tough-octopus-19

@SebasOfEek #css

star

Sat Aug 17 2024 01:20:17 GMT+0000 (Coordinated Universal Time)

@mebean #flutter #laravel #api #http #2lancer

star

Sat Aug 17 2024 00:58:14 GMT+0000 (Coordinated Universal Time)

@mebean #flutter #laravel #api #http #2lancer

star

Sat Aug 17 2024 00:56:17 GMT+0000 (Coordinated Universal Time)

@mebean #flutter #laravel #api #http #2lancer

star

Sat Aug 17 2024 00:55:54 GMT+0000 (Coordinated Universal Time)

@mebean #flutter #laravel #api #http #2lancer

star

Sat Aug 17 2024 00:54:26 GMT+0000 (Coordinated Universal Time) https://2lancer.ma/page/terms

@mebean #flutter #laravel #api #http #2lancer

star

Fri Aug 16 2024 20:39:04 GMT+0000 (Coordinated Universal Time)

@ASPX #css #html

star

Fri Aug 16 2024 20:08:36 GMT+0000 (Coordinated Universal Time) https://onecompiler.com/javascript

@muneeb

star

Fri Aug 16 2024 17:39:40 GMT+0000 (Coordinated Universal Time) https://github.com/SalesforceFoundation

@shawnclevinger

star

Fri Aug 16 2024 17:39:05 GMT+0000 (Coordinated Universal Time) https://github.com/developerforce

@shawnclevinger

star

Fri Aug 16 2024 17:38:25 GMT+0000 (Coordinated Universal Time) https://github.com/SalesforceLabs

@shawnclevinger

star

Fri Aug 16 2024 16:54:01 GMT+0000 (Coordinated Universal Time) flow_action_components/DedupeRecordCollection/config/project-scratch-def.json

@shawnclevinger

star

Fri Aug 16 2024 16:52:01 GMT+0000 (Coordinated Universal Time) flow_action_components/DedupeRecordCollection/config/project-scratch-def.json

@shawnclevinger

star

Fri Aug 16 2024 15:50:01 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/

@shawnclevinger

star

Fri Aug 16 2024 15:48:52 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/

@shawnclevinger

star

Fri Aug 16 2024 15:48:19 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/

@shawnclevinger

star

Fri Aug 16 2024 15:45:38 GMT+0000 (Coordinated Universal Time) https://unofficialsf.com/load-a-visualforce-page-with-parameters-in-lightning/

@shawnclevinger

star

Fri Aug 16 2024 08:00:42 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html

@amccall23

star

Fri Aug 16 2024 08:00:27 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html

@amccall23

star

Fri Aug 16 2024 07:59:42 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html

@amccall23

star

Fri Aug 16 2024 07:59:32 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html

@amccall23

star

Fri Aug 16 2024 07:59:29 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html

@amccall23

star

Fri Aug 16 2024 07:59:26 GMT+0000 (Coordinated Universal Time) https://www.raspberrypi.com/documentation/services/connect.html

@amccall23

star

Fri Aug 16 2024 04:52:54 GMT+0000 (Coordinated Universal Time)

@iamkatmakhafola

star

Fri Aug 16 2024 02:03:41 GMT+0000 (Coordinated Universal Time)

@Curable1600 #windows

star

Fri Aug 16 2024 01:45:34 GMT+0000 (Coordinated Universal Time)

@thecowsays #javascript

star

Fri Aug 16 2024 01:35:18 GMT+0000 (Coordinated Universal Time)

@shawnclevinger

star

Fri Aug 16 2024 01:32:13 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/tag/apex

@shawnclevinger

star

Fri Aug 16 2024 01:30:04 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/tag/lwc

@shawnclevinger

star

Fri Aug 16 2024 01:27:37 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/tag/salesforce

@shawnclevinger

star

Fri Aug 16 2024 01:14:31 GMT+0000 (Coordinated Universal Time) www.codecademy.com

@thecowsays #javascript

star

Fri Aug 16 2024 01:07:22 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/64194b2a0eab1e0013c9cf4e

@shawnclevinger

star

Fri Aug 16 2024 01:03:12 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/5e03b21a12e79618db53832c

@shawnclevinger

star

Fri Aug 16 2024 01:01:50 GMT+0000 (Coordinated Universal Time) https://www.thiscodeworks.com/how-to-change-any-attribute-of-a-html-element-html-javascript-jsfunctions-dom-dommanipulation/5e2e022d77696f00148a2077

@shawnclevinger

star

Fri Aug 16 2024 00:59:16 GMT+0000 (Coordinated Universal Time)

@WXAPAC

star

Thu Aug 15 2024 20:40:03 GMT+0000 (Coordinated Universal Time) https://docs.stripe.com/api/customers/update

@acassell

star

Thu Aug 15 2024 18:09:55 GMT+0000 (Coordinated Universal Time)

@yahellopit

star

Thu Aug 15 2024 16:06:26 GMT+0000 (Coordinated Universal Time)

@jrg_300i #undefined

star

Thu Aug 15 2024 13:23:10 GMT+0000 (Coordinated Universal Time)

@jrg_300i #undefined

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension