• File: UserClientController.php
  • Full Path: /var/www/imalipartnersapi/app/Http/Controllers/UserClientController.php
  • Date Modified: 02/08/2023 9:47 PM
  • File size: 94.58 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

namespace App\Http\Controllers;

use App\Bank\Payment;
use App\Classes\GenerateImaliAccount;
use App\Classes\GenerateToken;
use App\Classes\GenerateUserId;
use App\Classes\Kyc;
use App\Classes\PartnerKyc;
use App\Classes\Record;
use App\Classes\SendSMS;
use App\Classes\SendSMSSislog;
use App\Classes\SmsManager;
use App\Classes\TransactionGeneration;
use App\GeneralAdvice;
use App\Imali\ImaliAccount;
use App\Imali\ImaliAccountConfig;
use App\Imali\MerchantAccount;
use App\Imali\MerchantContract;
use App\PaymentGeneration;
use App\PhoneValidation;
use App\PurchaseVoucher;
use App\Refund;
use App\Store;
use App\StoreAmountGeneration;
use App\User;
use App\UserClient;
use App\UserMobilePhone;
use App\VoucherType;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use DB;
use SoapClient;
use SoapFault;

class UserClientController extends Controller
{

    protected $username;
    protected $password;
    protected $topUpUrl;

    protected $client;
    protected $msid;

    protected $request;
    protected $requestRefund;
    protected $requestRefundConfirm;
    protected $token;
    protected $generatedPayment;

    protected SmsManager $smsManager;


    public function __construct()
    {
//        TESTE
        $this->username = "TEST_PAYTEK";
        $this->password = "TESTpassPAYtek";
        $this->topUpUrl = 'https://topupretail.com:18880/Service.asmx?wsdl';

//         PRODUCTION
//        $this->username = "PAYTEK_PROD";
//        $this->password = "fs.S}nf4:IGXT|R";
//        $this->topUpUrl = 'https://topupretail.com:18873/Service.asmx?wsdl';

        $options = array(
//            'cache_wsdl' => 0,
//            'trace' => 1,
            'exceptions' => 1,
            'trace' => true,
            'keep_alive' => false,
            'connection_timeout' => 5000,
            'cache_wsdl' => WSDL_CACHE_NONE,
            'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | SOAP_COMPRESSION_DEFLATE,
            'stream_context' => stream_context_create(array(
                'ssl' => array(
                    'verify_peer' => true,
                    'verify_peer_name' => true,
                    'allow_self_signed' => true,
//                    'ciphers'=>'RC4-SHA'
                )
            )));

        $this->client = new SoapClient($this->topUpUrl, $options);
        $this->msid = new TransactionGeneration();

        $this->smsManager = new SmsManager();

    }

    public function getLang()
    {
        return response()->json(['message' => trans('not_found_transaction')]);
    }

    public function checkTransactionStatus($transaction)
    {
        $pay = Payment::query()
            ->with(['store', 'customer', 'account'])
            ->where('partner_transaction_id', '=', $transaction)
            ->first();

        if (!$pay) {

            $pay = Payment::query()
                ->with(['store', 'customer', 'account'])
                ->where('transaction_id', '=', $transaction)
                ->first();

            if ($pay) {

                $pay->makeHidden([
                    'id', 'qrcode', 'firebase_token', 'device_name', 'store_id', 'user_client_id', 'updated_at',
                    'imali_account_id', 'merchant_id', 'sender_id', 'store_amount_generation_id', 'category_id',
                    'estado', 'estado_color', 'transaction_id', 'token', 'token_sent', 'used_points', 'received_points',
                    'client_id', 'payment_type', 'amount_debited', 'comissao', 'payment_id'
                ]);

                if ($pay->customer) {
                    $pay->customer->makeHidden(['id', 'status', 'profile', 'email', 'birthday', 'balance_visibility', 'country_code', 'email_verified_at', 'session_status', 'firebase_token', 'user_client_id', 'phone_reference', 'terminalCompanyName', 'terminalChannel', 'terminalID', 'client_id', 'created_at', 'updated_at',
                        'info_status', 'last_name', 'phone', 'bi', 'update_info_status', 'user_update_info_status', 'document_id', 'photo', 'user_id']);
                }

                if ($pay->account) {
                    $pay->account->makeHidden(['id', 'status', 'profile', 'email', 'birthday', 'balance_visibility', 'country_code', 'email_verified_at', 'session_status', 'firebase_token', 'user_client_id', 'phone_reference', 'terminalCompanyName', 'terminalChannel', 'terminalID', 'client_id', 'created_at', 'updated_at',
                        'info_status', 'bi', 'update_info_status', 'user_update_info_status', 'document_id', 'photo', 'user_id',
                        'imali_account_config', 'captive_balance', 'balance', 'points', 'reference'
                    ]);
                }

                $pay->store->makeHidden([
                    'id', 'qrcode', 'firebase_token', 'device_name', 'store_id', 'user_client_id', 'created_at', 'updated_at',
                    'updated_at', 'user_id', 'industry_activity', 'merchant_contract_id', 'merchant_account_id',
                    'longitude', 'latitude', 'balance', 'session_status', 'photo', 'logo', 'status', 'email', 'qrcode'
                ]);

                if (\auth()->user()->id != $pay->client_id) {
                    return response()->json(['message' => trans('not_allowed_on_store')], 400);
                } else {
                    return response()->json($pay);
                }
            } else {

                return response()->json(['message' => trans('not_found_transaction')], 400);
            }

        } else {

            $pay->makeHidden([
                'id', 'qrcode', 'firebase_token', 'device_name', 'store_id', 'user_client_id', 'updated_at',
                'imali_account_id', 'merchant_id', 'sender_id', 'store_amount_generation_id', 'category_id',
                'estado', 'estado_color', 'transaction_id', 'token', 'token_sent', 'used_points', 'received_points',
                'client_id', 'payment_type', 'amount_debited', 'comissao', 'payment_id'
            ]);

            if ($pay->customer) {
                $pay->customer->makeHidden(['id', 'status', 'profile', 'email', 'birthday', 'balance_visibility', 'country_code', 'email_verified_at', 'session_status', 'firebase_token', 'user_client_id', 'phone_reference', 'terminalCompanyName', 'terminalChannel', 'terminalID', 'client_id', 'created_at', 'updated_at',
                    'info_status', 'phone', 'last_name', 'bi', 'update_info_status', 'user_update_info_status', 'document_id', 'photo', 'user_id']);
            }

            if ($pay->account) {
                $pay->account->makeHidden(['id', 'status', 'profile', 'email', 'birthday', 'balance_visibility', 'country_code', 'email_verified_at', 'session_status', 'firebase_token', 'user_client_id', 'phone_reference', 'terminalCompanyName', 'terminalChannel', 'terminalID', 'client_id', 'created_at', 'updated_at',
                    'info_status', 'bi', 'update_info_status', 'user_update_info_status', 'document_id', 'photo', 'user_id',
                    'imali_account_config', 'captive_balance', 'balance', 'points', 'reference'
                ]);
            }

            $pay->store->makeHidden([
                'id', 'qrcode', 'firebase_token', 'device_name', 'store_id', 'user_client_id', 'created_at', 'updated_at',
                'updated_at', 'user_id', 'industry_activity', 'merchant_contract_id', 'merchant_account_id',
                'longitude', 'latitude', 'balance', 'session_status', 'photo', 'logo', 'status', 'email', 'qrcode'
            ]);

            if (\auth()->user()->id != $pay->client_id) {
                return response()->json(['message' => trans('not_allowed_on_store')], 400);
            } else {
                return response()->json($pay);
            }
        }

    }

    public function getTransaction(Request $request, $transaction)
    {
        $token = str_replace('Bearer ', '', $request->header('authorization'));

        $userClient = UserClient::query()
            ->where('client_key', '=', $token)
            ->first();

        $pay = PaymentGeneration::query()
            ->where('payment_generations.partner_transaction_id', '=', $transaction)
            ->first();

        if (!$pay) {
            return response()->json(['message' => trans('not_found_transaction')], 400);
        } else {

            if ($userClient->id != $pay->user_client_id) {
                return response()->json(['message' => trans('not_allowed_on_store')], 400);
            } else {

                $payment = PaymentGeneration::query()
                    ->with(['store', 'customer'])
                    ->where('payment_generations.partner_transaction_id', '=', $transaction)
                    ->get();

                if ($payment) {

                    $payment->makeHidden([
                        'merchant_id', 'imali_account_id', 'user_id', 'token', 'user_client_id', 'token_sent',
                        'id', 'estado_color', 'sender_id', 'store_id', 'client_id', 'updated_at', 'category_id',
                        'stores.id', 'store.status', 'store.session_status', 'store.firebase_token', 'store.user_client_id', 'store.merchant_account_id', 'store.merchant_contract_id', 'store.industry_activity',
                        'store.user_id', 'store.created_at', 'store.updated_at', 'customer.id', 'customer.profile', 'customer.status', 'customer.email', 'customer.birthday', 'customer.balance_visibility',
                        'customer.country_code', 'customer.email_verified_at', 'customer.firebase_token', 'customer.phone_reference', 'customer.terminalCompanyName', 'customer.terminalChannel', 'customer.terminalID', 'customer.client_id', 'customer.info_status',
                        'customer.update_info_status', 'customer.user_update_info_status', 'customer.document_id', 'customer.created_at', 'customer.updated_at',
                    ]);

                    foreach ($payment as $store) {
                        $store->store->makeHidden(['id', 'status', 'session_status', 'firebase_token', 'user_client_id', 'merchant_account_id', 'merchant_contract_id', 'industry_activity', 'user_id', 'created_at', 'updated_at', 'latitude', 'longitude', 'balance']);
                        $store->customer->makeHidden(['id', 'status', 'profile', 'email', 'birthday', 'balance_visibility', 'country_code', 'email_verified_at', 'session_status', 'firebase_token', 'user_client_id', 'phone_reference', 'terminalCompanyName', 'terminalChannel', 'terminalID', 'client_id', 'created_at', 'updated_at',
                            'info_status', 'update_info_status', 'user_update_info_status', 'document_id', 'photo', 'user_id']);

                        $store->account->makeHidden(['id', 'points', 'balance', 'captive_balance', 'user_id', 'imali_account_config', 'created_at', 'updated_at']);
                    }

                    return response()->json($payment);
                } else {
                    return response()->json(['message' => trans('not_found_transaction')], 400);
                }

            }


        }


    }


    public function getAccount(Request $request)
    {

        return response()->json($request->user()->makeHidden(['id', 'created_at', 'updated_at', 'email_verified_at', 'session_status', 'url', 'user_type'
            , 'client_key', 'status']));
    }

    public function getVoucherType()
    {
        $data = VoucherType::query()
            ->where('status', 'disponivel')
            ->where('type', 'recarga')
            ->select('name', 'code', 'type', 'logo', 'created_at', 'updated_at')
            ->get();
        return response()->json(['data' => $data], 200);
    }

    public function getUserVoucher(Request $request)
    {

        $this->validate($request, [
            'accountNumber' => 'required|min:9|max:9'
        ]);

        $token = str_replace('Bearer ', '', $request->header('authorization'));
        $clientStore = UserClient::query()->where('client_key', $token)->first();

        $kyc = new PartnerKyc();

        $result = $kyc->checkImaliAccount($request);

        if ($result) {
            return $result;
        } else {
            $user = User::query()
                ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
                ->where('imali_accounts.account_number', $request->accountNumber)
                ->select('users.*')
                ->first();

            $data = PurchaseVoucher::query()
                ->where('user_id', $user->id)
                ->where('client_id', $clientStore->id)
                ->orderByDesc('created_at')
                ->get();

            $data->makeHidden(['id', 'user_id', 'client_id', 'voucher_list_id', 'comissao', 'transaction', 'price', 'voucherinfo']);

            return response()->json(['data' => $data], 200);
        }


    }

    public function getVoucherList()
    {
        try {
            $msid = new TransactionGeneration();
            $params = array(
                'req' => array(
                    'authCred' => array(
                        'opName' => $this->username,
                        'password' => $this->password
                    ),
                    'msgID' => $msid->generateMSID(),
                    'terminalID' => 'APP',
                    'terminalMsgID' => '202001070006'
                )
            );
            $data = json_decode(json_encode($params), true);
            $client = new SoapClient($this->topUpUrl, ['trace' => true]);
            $response = $client->VoucherList($data);

            return response()->json(['data' => $response->VoucherListResult->voucherlist->VoucherInfo]);

        } catch (SoapFault $fault) {
            echo '<br>' . $fault;
        }
    }

    public function buyVoucher(Request $request)
    {
        $this->validate($request, [
            'pin' => 'required|min:4|max:4',
            'accountNumber' => 'required',
            'voucher' => 'required',
            'transactionID' => 'required',
//            'amount' => 'required',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
            'terminalCompanyName' => 'required'
        ], [
            'pin.required' => 'O Pin é Obrigatório',
            'accountNumber.required' => 'O accountNumber é Obrigatório',
            'voucher.required' => 'O voucher é Obrigatório',
            'terminalCompanyName.required' => 'O campo terminalCompanyName é Obrigatório',
            'terminalID.required' => 'terminalID é Obrigatório',
            'terminalChannel.required' => 'terminalChannel é Obrigatório',
        ]);
        $user = User::query()
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
            ->where('imali_accounts.account_number', $request->accountNumber)
            ->first();

//        $voucherAmount = intval(preg_replace('/[^0-9]+/', '', $request->voucher), 10);

        try {

            $kyc = new PartnerKyc();

            $result = $kyc->checkPaymentVoucher($request);

            if ($result) {
                return $result;
            } else {
                $msid = new TransactionGeneration();
//                $transaction = $msid->generateMSID();
                $transaction = $this->msid->generateMSID();

                $params = array(
                    'req' => array(
                        'authCred' => array(
                            'opName' => $this->username,
                            'password' => $this->password
                        ),
                        'terminalMsgID' => '202001070006',
//                        'msgID' => $request->transactionID,
                        'msgID' => $transaction,
                        'test' => true,
                        'order' => array(
                            'VoucherOrder' => array(
                                'vouchercode' => $request->voucher,
//                                    'vouchercode' => 'VOM000010',
                                'qty' => 1
                            )
                        ),
                        'receiptFormat' => 'POR_FORMATED_50',
                        'terminalChannel' => $request->terminalChannel,
                        'terminalCompanyName' => $request->terminalCompanyName,
                        'terminalID' => $request->terminalID,
                        'terminalOperator' => 'Operator'
                    )
                );
                $data = json_decode(json_encode($params), true);

                $response = $this->client->PurchaseVoucher($data);


                $res = $response->PurchaseVoucherResult;
                $token = str_replace('Bearer ', '', $request->header('authorization'));
                $clientStore = UserClient::query()->where('client_key', $token)->first();

                if ($response->PurchaseVoucherResult->hasFault === false) {
                    $voucher = $response->PurchaseVoucherResult->vouchers->Voucher;
                    $voucherInfo = $response->PurchaseVoucherResult->vouchers->Voucher->voucherinfo;

                    $recarga = PurchaseVoucher::create([
//                        'transaction' => $response->transaction,
                        'vouchername' => $voucherInfo->vouchername,
                        'vouchercode' => $voucherInfo->vouchercode,
                        'vouchervalue' => $voucherInfo->vouchervalue,
                        'barcode' => $voucherInfo->barcode,
//                            'price' => $voucherInfo->price,
                        'price' => $voucherInfo->vouchervalue,
                        'comissao' => $voucherInfo->vouchervalue - $voucherInfo->price,
                        'reqterminalMsgID' => $res->reqterminalMsgID,
                        'reqterminalID' => $res->reqterminalID,
                        'reqMsgID' => $res->reqMsgID,
                        'respDateTime' => $res->respDateTime,
//                        'voucherinfo' => $voucherInfo,
                        'serial' => $voucher->serial,
                        'pin' => $voucher->pin,
                        'datepurchased' => $voucher->datepurchased,
                        'receiptFormat' => $voucher->receiptFormat,
                        'receipt' => $voucher->receipt,
                        'smsreceipt' => $voucher->smsreceipt,
                        'user_id' => $user->id,
                        'voucher_list_id' => null,
                        'type' => 'recarga',
                        'client_id' => $clientStore->id,
                        'terminalChannel' => $request->terminalChannel,
                        'terminalCompanyName' => $request->terminalCompanyName,
                        'terminalID' => $request->terminalID,
                    ]);

                    $imaliUser = ImaliAccount::query()->where('account_number', $request->accountNumber)->first();

                    $totalAmount = $recarga->vouchervalue + $imaliUser->taxa;

                    DB::table('imali_accounts')->where('user_id', $user->id)->decrement('balance', $totalAmount);

//                        $sms = new SendSMS();
//
//                        $sms->sendSMSPurchaseVoucher($response->PurchaseVoucherResult->vouchers->Voucher, $response->PurchaseVoucherResult->vouchers->Voucher->voucherinfo->vouchername, auth()->user()->phone);

                    $notification = array(
                        'icon' => 'ic_i_mali_cover',
                        'title' => 'i.Mali recargas',
                        'body' => 'Parabéns, ' . ' comprou recarga ' . $recarga->vouchername . '.' . ' i.Mali é o Futuro',
                        'click_action' => 'com.imali.payapp.payment_RECARGA_NOTIFICATION',
                        'color' => '#ffffff'
                    );

                    $data = array(
                        'reqMsgID' => $recarga->reqMsgID,
                        'vouchername' => $recarga->vouchername,
                        'vouchercode' => (double)$recarga->vouchercode,
                        'data' => $recarga->created_at,
                        'pin' => $recarga->pin,
                        'serial' => $recarga->serial,
                        'price' => $recarga->price,
                        'vouchervalue' => $recarga->vouchervalue,
                        'sms' => $recarga->receipt,
                        'terminal' => 'firebase'
                    );
                    $this->pushNotifification($user->firebase_token, $notification, $data);

                    return response()->json([
                        'message' => 'Compra Feita com Sucesso!',
                        'transaction' => $request->transactionID,
//                        'data' => $response->PurchaseVoucherResult,
                        'vouchername' => $voucherInfo->vouchername,
                        'vouchercode' => $voucherInfo->vouchercode,
                        'vouchervalue' => $voucherInfo->vouchervalue,
                        'barcode' => $voucherInfo->barcode,
                        'serial' => $voucher->serial,
                        'pin' => $voucher->pin,
                    ], 200);

                } else {

                    if ($response->PurchaseVoucherResult->fault->mustALR === true) {

                        $imaliUser = ImaliAccount::query()->where('user_id', $user->id)->first();
                        $totalAmount = $request->amount + $imaliUser->taxa;
                        DB::table('imali_accounts')->where('user_id', $user->id)->increment('captive_balance', $totalAmount);

//                        return response()->json(['message' => $response->PurchaseVoucherResult], 405);

                        GeneralAdvice::create([
                            'reqMsgID' => $response->PurchaseVoucherResult->reqMsgID,
                            'reqterminalID' => $response->PurchaseVoucherResult->reqterminalID,
//                            'receiptFormat' => $response->PurchaseVoucherResult->receiptFormat,
                            'receiptFormat' => 'POR_FORMATED_50',
                            'respDateTime' => $response->PurchaseVoucherResult->respDateTime,
                            'faultNumber' => $response->PurchaseVoucherResult->fault->faultnumber,
                            'user_id' => $user->id,
                            'type' => 'direct',
//                            'amount' => $request->voucher . substr(4, 4),
                            'amount' => $request->amount,
                            'message' => $response->PurchaseVoucherResult->fault->POR_operatorMsg,
                            'msno' => $request->voucher,
                            'description' => $request->voucher,
                            'client_id' => $clientStore->id,
                            'terminalChannel' => $request->terminalChannel,
                            'terminalCompanyName' => $request->terminalCompanyName,
                            'terminalID' => $request->terminalID,
                        ]);
                        return response()->json(['message' => $response->PurchaseVoucherResult->fault->POR_operatorMsg], 405);

                    } else {
                        return response()->json(['message' => $response->PurchaseVoucherResult->fault->POR_operatorMsg], 400);
                    }

                }


            }
        } catch (SoapFault $fault) {
            echo '<br>' . $fault;
        }
    }

    public function getUserInfo($accountNumber, Request $request)
    {
        $user = User::query()
            ->join('imali_accounts', 'users.id', '=', 'imali_accounts.user_id')
            ->where('account_number', $accountNumber)
            ->first();

        $user->makeHidden(['id', 'user_id', 'client_id', 'profile', 'status', 'birthday', 'bi', 'terminalID', 'terminalChannel', 'terminalCompanyName', 'email_verified_at',
            'firebase_token', 'phone_reference', 'created_at', 'updated_at', 'imali_account_config', 'captive_balance', 'country_code', 'photo', 'email', 'points', 'phone', 'balance_visibility',
            'update_info_status', 'user_update_info_status', 'document_id', 'info_status'
        ]);
//        $token = str_replace('Bearer ', '', $request->header('authorization'));
//        $clientStore = UserClient::query()->where('client_key', $token)->first();

        $kyc = new PartnerKyc();

        $result = $kyc->checkImaliAccount($request);

        if ($result) {
            return $result;
        } else {
            return response()->json($user);
        }
    }

    public function IntegrateImaliAccount(Request $request)
    {
        $this->validate($request, [
            'accountNumber' => 'required|min:9|max:9',
            'pin' => 'required|min:4|max:4',
        ]);

        $user = User::query()
            ->join('imali_accounts', 'users.id', '=', 'imali_accounts.user_id')
            ->where('account_number', $request->accountNumber)
            ->first();

        if ($user) {
            if (Hash::check($request->pin, $user->pin)) {
                return response()->json(['message' => 'Conta verificada']);
            } else {
                return response()->json(['message' => 'Pin incorrecto'], 405);
            }
        } else {
            return response()->json(['message' => 'Conta inválida'], 400);
        }

    }

    function saveClientIntegrator(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|min:3|max:50',
            'institution' => 'required|unique:user_clients|min:3',
            'phone' => 'required|unique:user_clients|min:9|integer',
            'email' => 'required|email|unique:user_clients,email',
            'nuit' => 'required|min:9|integer',
        ], [
            'email.required' => 'O Campo Email é de carácter Obrigatório',
            'email.unique' => 'Este Email já está em uso',
            'phone.required' => 'O Número do celular é obrigatório',
            'phone.unique' => 'O Número do celular já está em uso',
            'phone.min' => 'O Campo Celular deve ter 9 dígitos',
            'name.required' => 'O Campo Nome é obrigatório',
            'institution.required' => 'O Campo Institution é obrigatório',
            'nuit.required' => 'O campo Nuit é Obrigatório',
            'nuit.min' => 'O campo nuit ter 9 dígitos',
        ]);


        $client = UserClient::create([
            'name' => $request->name,
            'email' => $request->email,
            'phone' => $request->phone,
            'institution' => $request->institution,
            'password' => Hash::make('12345678'),
            'nuit' => $request->nuit,
            'user_type' => $request->user_type
        ]);


        $token = $client->createToken('api_token')->plainTextToken;

        $client->update(['client_key' => $token]);

//        Mail::to($client->email)->send(new ImaliIntegration($client));

        return response()->json(['message' => 'Cliente Integrador Adicionado com Sucesso', 'api_token' => $token]);

    }

    function revokeToken(Request $request)
    {
        $request->user()->tokens()->delete();
        auth()->user()->tokens()->delete();

        return response()->json(['message' => 'Logout feito com sucesso!']);
    }

    public function updateUserClient(Request $request)
    {
        $values = $this->validate($request, [
            'email' => 'required|email',
//            'password' => 'required|min:8'
        ]);

        $userClient = UserClient::query()
            ->where('email', '=', $values['email'])
            ->first();

//        if (!Auth::attempt($values)) {
//        if (!Hash::check($values['password'], $userClient->password)) {
//            return response()->json(['message' => 'Credenciais incorrectos'], 403);
//        } else {

//            $token = $userClient->createToken('secret')->plainTextToken;
        $userClient->update(['client_key' => $request->token]);

        return response()->json([
//                'user' => auth()->user(),
            'user' => $userClient,
            'token' => $request->token
//                'token' => auth()->user()->createToken('secret')->plainTextToken
        ]);
//        }
    }

    public function loginUserClient(Request $request)
    {
        $values = $this->validate($request, [
            'email' => 'required|email',
            'password' => 'required|min:8'
        ]);

        $userClient = UserClient::query()
            ->where('email', '=', $values['email'])
            ->first();

//        if (!Auth::attempt($values)) {
        if ($userClient) {
            if (!Hash::check($values['password'], $userClient->password)) {
                return response()->json(['message' => 'Credenciais incorrectos'], 403);
            } else {

                $token = $userClient->createToken('secret')->plainTextToken;
                $userClient->update(['client_key' => $token]);
                return response()->json([
//                'user' => auth()->user(),
                    'user' => $userClient,
                    'token' => $token
//                'token' => auth()->user()->createToken('secret')->plainTextToken
                ]);
            }
        } else {
            return response()->json(['message' => 'User account not found'], 404);
        }

    }


    public function saveToken(Request $request)
    {

        $this->validate($request, [
            'client_id' => 'required'
        ]);
        $client = UserClient::find($request->client_id);

        if ($client) {

            $token = $client->createToken('api_token')->plainTextToken;

            UserClient::query()
                ->where('id', '=', $request->client_id)
                ->update(['client_key' => $token]);

            return response()->json(['api_token' => $token]);
        } else {
            return response()->json(['message' => 'Client Not Found'], 400);
        }

    }

    public function getClients()
    {
        $users = UserClient::query()->get();

        return response()->json($users);
    }

    public function getStoreQrcode(Request $request, $accountNumber)
    {
        $kyc = new PartnerKyc();
        $checkKyc = $kyc->checkGetTransactions($request, $accountNumber);

        if ($checkKyc) {
            return $checkKyc;
        } else {
            $store = Store::query()
                ->where('account_number', $accountNumber)
                ->select('qrcode', 'public_id')
                ->first();
            return response()->json(['qrcode_url' => $store->qrcode, 'store_reference' => $store->public_id], 200);
        }
    }

    public function QrcodeTransaction(Request $request)
    {
        $this->validate($request, [
            'amount' => 'required',
            'accountNumber' => 'required',
            'transactionID' => 'required|min:12',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
            'terminalCompanyName' => 'required'
        ], [
            'accountNumber.required' => 'O Campo accountNumber é Obrigatório',
            'transactionID.required' => 'O Campo transactionId é Obrigatório',
            'amount.required' => 'O Campo amount é Obrigatório',
            'terminalCompanyName.required' => 'O campo terminalCompanyName é Obrigatório',
            'terminalID.required' => 'terminalID é Obrigatório',
            'terminalChannel.required' => 'terminalChannel é Obrigatório',
        ]);

        $kyc = new PartnerKyc();

        $result = $kyc->checkIntegrador($request);

        if ($result) {
            $log = new Record();
            $log->createLog([
                'description' => 'Gerar Qrcode Partner',
                'details' => $request,
                'operation' => 'Falha',
                'properties' => json_encode($request->all()),
                'origin_request' => $request->url(),
                'origin_ip' => $request->ip(),
                'status' => 'error',
                'user_id' => $request->user()->id
            ]);
            return $result;
        } else {
            $checkStore = Store::query()
                ->join('merchant_accounts', 'merchant_accounts.id', '=', 'stores.merchant_account_id')
                ->where('stores.account_number', $request->accountNumber)
                ->select('stores.*', 'merchant_accounts.institution')
                ->first();
            $token = str_replace('Bearer ', '', $request->header('authorization'));
            $userClient = UserClient::query()->where('client_key', $token)->first();

            if ($checkStore) {
                if (is_numeric($request->amount)) {
                    $res = StoreAmountGeneration::create([
                        'transaction' => \Ramsey\Uuid\Uuid::uuid4(),
                        'partner_transaction_id' => $request->transactionID,
                        'amount' => $request->amount,
                        'store_id' => $checkStore->id,
                        'firebase_token' => $request->firebase_token,
                        'terminalID' => $request->terminalID,
                        'terminalChannel' => $request->terminalChannel,
                        'terminalCompanyName' => $request->terminalCompanyName,
                        'user_client_id' => $userClient->id
                    ]);
                    return response()->json(['message' => 'Transacção Gerada com Sucesso',
                        'amount' => $res->amount,
                        'transaction' => $res->transaction,
//                        'transaction' => $res->partner_transaction_id,
                        'account_number' => $checkStore->account_number,
                        'address_store' => $checkStore->address,
//                        'duration' => $res->duration,
//                        'status' => $res->status,
                        'institution' => $checkStore->institution,
                        'promo' => 'Compra Recargas com Zero Taxas no i.Mali'], 201);
                } else {
                    return response()->json(['message' => 'Introduza um montante válido'], 407);
                }
            } else
                return response()->json(['message' => 'Loja Inválida'], 404);
        }

    }

    public function Qrcode(Request $request)
    {
        $this->validate($request, [
            'amount' => 'required',
            'accountNumber' => 'required',
            'transactionID' => 'required|min:12',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
            'terminalCompanyName' => 'required'
        ]);

        $kyc = new PartnerKyc();

        $result = $kyc->checkIntegrador($request);

        if ($result) {
            $log = new Record();
            $log->createLog([
                'description' => 'Gerar Qrcode Partner',
                'details' => $request,
                'operation' => 'Falha',
                'properties' => json_encode($request->all()),
                'origin_request' => $request->url(),
                'origin_ip' => $request->ip(),
                'status' => 'error',
                'user_id' => $request->user()->id
            ]);
            return $result;
        } else {
            $checkStore = Store::query()
                ->join('merchant_accounts', 'merchant_accounts.id', '=', 'stores.merchant_account_id')
                ->where('stores.account_number', '=', $request->accountNumber)
                ->select('stores.*', 'merchant_accounts.institution')
                ->first();

            $token = str_replace('Bearer ', '', $request->header('authorization'));
            $userClient = UserClient::query()->where('client_key', $token)->first();

            if ($checkStore) {
                if (is_numeric($request->amount)) {
                    $res = Payment::create([
                        'transaction_id' => $request->transactionID,
                        'partner_transaction_id' => $request->transactionID,
                        'amount' => $request->amount,
                        'store_id' => $checkStore->id,
                        'status' => 'pending',
                        'estado' => 'pending',
                        'firebase_token' => $request->firebase_token,
                        'terminalID' => $request->terminalID,
                        'terminalChannel' => $request->terminalChannel,
                        'terminalCompanyName' => $request->terminalCompanyName,
                        'client_id' => $userClient->id
                    ]);

                    return response()->json([
                        'message' => trans('transaction_generated'),
                        'amount' => $res->amount,
                        'transaction' => $res->transaction_id,
                        'account_number' => $checkStore->account_number,
                        'address_store' => $checkStore->address,
                        'institution' => $checkStore->institution,
                        'promo' => trans('promo')], 201);
                } else {
                    return response()->json(['message' => trans('insert_valid_amount')], 407);
                }
            } else
                return response()->json(['message' => trans('invalid_store')], 404);
        }

    }

    public function getBalance($account_number)
    {
        if (is_numeric($account_number)) {
            $userBalance = ImaliAccount::query()
                ->where('account_number', $account_number)
                ->select('balance')
                ->first();

            if ($userBalance) {
                return response()->json($userBalance);
            } else {
                return response()->json(['message' => 'Conta inválida'], 400);
            }
        } else {
            return response()->json(['message' => 'Conta i.Mali contém apenas dígitos numéricos'], 400);
        }

    }

    public function addStoreToUserClient(Request $request)
    {
        $this->validate($request, [
            'store_account_number' => 'required',
            'user_client_id' => 'required',
//            'id' => 'required',
        ], [
            'account_number.required' => 'campo store_account_number é de carácter obrigatório',
//            'id.required' => 'Campo id é obrigatório',
            'user_client_id.required' => 'Campo user_client_id é obrigatório',
        ]);
        $store = Store::query()
            ->where('account_number', $request->store_account_number)
//            ->where('account_number', $request->account_number)
//            ->where('id', $request->id)
            ->first();

        $checkIntegration = Store::query()
            ->where('account_number', $request->store_account_number)
            ->where('user_client_id', $request->user_client_id)
            ->where('id', $request->id)
            ->first();

        if ($checkIntegration) {
            return response()->json(['message' => 'Está integração já foi feita!'], 400);
        } else {

            if ($store) {
                $store->update([
                    'user_client_id' => $request->user_client_id
                ]);

                return response()->json(['message' => 'Lojá integrada com Sucesso'], 200);
            } else {
                return response()->json(['message' => 'Lojá inválida'], 400);
            }

        }


    }

    public function sendToken(Request $request)
    {
        $this->validate($request, [
            'name' => 'required',
            'phone' => 'required|unique:users|min:9',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|min:8',
            'password_confirmation' => 'required|min:8',
            'terminalID' => 'required',
//            'country_code' => 'required',
            'terminalChannel' => 'required',
            'terminalCompanyName' => 'required',
        ], [
            'email.required' => 'O Campo Email é de carácter Obrigatório',
            'email.unique' => 'Este Email já está em uso',
            'phone.required' => 'O Número do celular é obrigatório',
            'phone.unique' => 'O Número do celular já está em uso',
            'phone.min' => 'O Campo Celular deve ter 9 dígitos',
            'name.required' => 'O Campo Nome é obrigatório',
//            'bi.required' => 'O campo Bi é Obrigatório',
//            'bi.min' => 'O campo Bi ter 13 dígitos',
            'password.required' => 'O Campo Senha é obrigatório',
            'password.confirmed' => 'Senhas incompatíveis',
            'password.min' => 'A senha deve ter 8 digitos no mínimo',
            'terminalChannel.required' => 'terminalChannel é Obrigatório',
            'terminalID.required' => 'terminalID é Obrigatório',
            'terminalCompanyName.required' => 'terminalCompanyName é Obrigatório',
//            'country_code.required' => 'country_code é Obrigatório'
        ]);

        $token = new GenerateToken();
        $data = ['phone' => $request->country_code . $request->phone, 'codigo' => $token->generatePhoneNumberCode()];
//        $sms = new  SendSMS();
//        $sent = $sms->verifyUser($data);
//        $sislog = new SendSMSSislog();
//        $sent = $sislog->smsVerifyUser($data);

//        if ($sent) {

        $validate = PhoneValidation::query()->where('phone', $request->phone)->count();

        if ($validate === 0) {
            $save = PhoneValidation::create([
                'phone' => $request->phone,
//                'country_code' => $request->country_code,
                'country_code' => +258,
                'expire_at' => now(),
                'duration' => 5,
                'codigo' => $data['codigo'],
                'is_Validated' => 0
            ]);
            if ($save) {
                return response()->json(['codigo' => $data['codigo'], 'message' => 'Codigo de Verificação enviado com sucesso!'], 200);
            }
        } else {
            $validate = PhoneValidation::query()->where('phone', $request->phone)->first();
            $save = $validate->update(['codigo' => $data['codigo']]);
            if ($save) {
                return response()->json(['message' => 'Codigo de Verificação enviado com sucesso!', 'codigo' => $data['codigo']], 200);
            }
        }

//        }

    }

    public function checkCodigo(Request $request)
    {
        $this->validate($request, [
            'codigo' => 'required',
            'phone' => 'required',
        ], [
//            'codigo.required' => 'O Campo Email é de carácter Obrigatório',
//            'phone.required' => 'O Número do celular é obrigatório',
        ]);

        try {
            $validate = PhoneValidation::query()->where('phone', $request->phone)->where('codigo', $request->codigo)->count();
            $getPhone = PhoneValidation::query()->where('phone', $request->phone)->where('codigo', $request->codigo)->first();
            if ($validate > 0) {

                $log = new Record();
                $log->createLog([
                    'description' => $request->phone,
                    'details' => 'Celular Verificado com Successo!',
                    'operation' => 'Check Phone Validation',
                    'status' => 'Success',
                    'user_id' => 1
                ]);
                $getPhone->update(['is_Validated' => 1]);
                return response()->json(['message' => 'Celular Verificado com Successo!'], 200);
            } else {

                $log = new Record();
                $log->createLog([
                    'description' => $request->phone,
                    'details' => 'Código inválido',
                    'operation' => 'Check Phone Validation',
                    'status' => 'Error',
                    'user_id' => 1
                ]);

                return response()->json(['message' => 'Código inválido'], 400);
            }
        } catch (Exception $exception) {
            return response()->json($exception);
        }
    }

    public function registerUser(Request $request)
    {
        $this->validate($request, [
            'name' => 'required',
            'phone' => 'required|unique:users|min:9',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|max:8',
            'pin' => 'required|min:4|max:4',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
//            'description' => 'required',
            'terminalCompanyName' => 'required',
//            'bi' => 'required|min:13'
        ], [
            'email.required' => 'O Campo Email é de carácter Obrigatório',
            'email.unique' => 'Este Email já está em uso',
            'phone.required' => 'O Número do celular é obrigatório',
            'phone.unique' => 'O Número do celular já está em uso',
            'phone.min' => 'O Campo Celular deve ter 9 dígitos',
            'name.required' => 'O Campo Nome é obrigatório',
            'bi.required' => 'O campo Bi é Obrigatório',
            'bi.min' => 'O campo Bi ter 13 dígitos',
            'password.required' => 'O Campo Senha é obrigatório',
            'password.confirmed' => 'Senhas incompatíveis',
            'password.min' => 'A senha deve ter 8 digitos no mínimo',
            'terminalChannel.required' => 'terminalChannel é Obrigatório'
        ]);

        $getPhone = PhoneValidation::query()
            ->where('phone', $request->phone)
            ->where('is_Validated', '=', 1)
            ->first();

        if (!$getPhone) {
            return response()->json(['message' => 'O Nr do Celular não confere ou Nr não validado.'], 401);
        }


        $generate = new GenerateUserId();
        $randomString = $generate->generatedUserId(30);


        $user = User::create([
            'firebase_token' => request('firebase_token'),
            'mobile_reference' => request('mobile_reference'),
            'name' => request('name'),
            'email' => request('email'),
            'phone' => request('phone'),
//            'bi' => request('bi'),
            'pin' => Hash::make(request('pin')),
            'user_id' => $randomString,
            'password' => bcrypt(request('password')),
        ]);

        $mobile = UserMobilePhone::query()
            ->where('user_id', $request->user()->id)
            ->where('firebase_token', $request->firebase_token)
            ->where('mobile_reference', $request->mobile_reference)
            ->first();

//        if (!$mobile) {
//            $mobile->create([
//                'firebase_token' => $request->firebase_token,
//                'mobile_reference' => $request->mobile_reference,
//                'user_id' => $user->id
//            ]);
//        } else {
////            $mobile->create([
////                'firebase_token' => $request->firebase_token,
////                'mobile_reference' => $request->mobile_reference,
////                'user_id' => $user->id
////            ]);
//        }

        $imali = new GenerateImaliAccount();
        $generateImaliAcount = $imali->GenerateImaliAccountNumberAndStore();
        $account = '';
        if ($generateImaliAcount) {
//            $imaliConfig = ImaliAccountConfig::find(4);
            $imaliConfig = ImaliAccountConfig::query()->first();
            $account = $user->imaliAccount()->create([
                'points' => 0,
                'user_id' => $user->id,
                'imali_account_config' => $imaliConfig->id,
                'account_number' => $generateImaliAcount,
                'reference' => $imali->generateReference(),
                'balance' => 0
            ]);
        }
        return response()->json(['message' => 'Conta Criada com Sucesso', 'accountNumber' => $account->account_number]);
    }

    public function getGeneratedPayments(Request $request, $accountNumber)
    {

        $kyc = new PartnerKyc();
        $checkKyc = $kyc->checkGetTransactions($request, $accountNumber);

        if ($checkKyc) {
            return $checkKyc;
        } else {

            $payments = Payment::query()
                ->join('stores', 'stores.id', '=', 'payments.store_id')
                ->orderByDesc('created_at')
                ->where('stores.account_number', '=', $accountNumber)
                ->whereDate('payments.created_at', '=', date('Y-m-d'))
                ->select('payments.*', 'stores.account_number as store_account_number')
                ->get();


            $payments->makeHidden([
                'id', 'user_id', 'imali_account_id', 'user_client_id', 'merchant_id',
                'store_id', 'token', 'token_sent', 'duration', 'updated_at', 'transaction_id',
                'estado', 'estado_color', 'firebase_token', 'device_name', 'sender_id', 'client_id',
                'payment_id', 'store_amount_generation_id', 'qrcode', 'refund_confirmation', 'comissao',
                'payment_type', 'received_points'
            ]);

            return response()->json(['data' => $payments]);
        }

    }

    public function getStorePayments(Request $request, $accountNumber)
    {

        $kyc = new PartnerKyc();
        $checkKyc = $kyc->checkGetTransactions($request, $accountNumber);

        if ($checkKyc) {
            return $checkKyc;
        } else {

            $payment = Payment::query()
                ->join('stores', 'stores.id', '=', 'payments.store_id')
                ->join('users', 'users.id', '=', 'payments.sender_id')
                ->join('imali_accounts', 'imali_accounts.user_id', '=', 'payments.sender_id')
                ->where('payments.client_id', '=', $request->user()->id)
                ->whereDate('payments.created_at', date('Y-m-d'))
                ->orderByDesc('payments.created_at')
                ->select('payments.*', 'stores.name as store_name', 'stores.account_number as store_account_number', 'imali_accounts.account_number as imali_account', 'users.name as imali_username')
                ->paginate(10);

            $payment->makeHidden([
                'id', 'comissao',
                'sender_id',
                'store_id',
                'client_id',
                'category_id',
                'estado_color',
                'updated_at',
                'used_points',
                'received_points',
                'transaction_id',
                'token', 'token_sent', 'qrcode', 'firebase_token', 'device_name', 'imali_account_id', 'merchant_id', 'payment_id', 'store_amount_generation_id',
                ''
            ]);

            return response()->json(['data' => $payment]);
        }

    }

    public function getRefunds(Request $request, $accountNumber)
    {
        $kyc = new PartnerKyc();
        $checkKyc = $kyc->checkGetTransactions($request, $accountNumber);

        if ($checkKyc) {
            return $checkKyc;
        } else {

            $payment = Payment::query()
                ->join('stores', 'stores.id', '=', 'payments.store_id')
                ->join('users', 'users.id', '=', 'payments.sender_id')
                ->join('imali_accounts', 'imali_accounts.user_id', '=', 'payments.sender_id')
                ->where('payments.client_id', '=', $request->user()->id)
                ->where('stores.account_number', '=', $accountNumber)
                ->whereDate('payments.created_at', '=', date('Y-m-d'))
                ->where('payments.payment_type', '=', 'refund')
                ->orderByDesc('payments.created_at')
                ->select('payments.*', 'stores.name as store_name', 'stores.account_number as store_account_number', 'imali_accounts.account_number as imali_account', 'users.name as imali_username', 'payments.transaction_id as payment_tarnsaction')
//                ->paginate(25)
                ->get();

            $payment->makeHidden([
                'id', 'comissao', 'sender_id', 'store_id', 'client_id', 'updated_at',
                'merchant_id', 'imali_user_id', 'user_client_id', 'payment_id', 'estado_color', 'token',
                'account_number', 'transaction_id', 'received_points', 'used_points', 'amount_credited', 'amount_debited',
                'token_sent', 'estado', 'duration', 'firebase_token', 'qrcode', 'device_name',
                'imali_account_id', 'store_amount_generation_id', 'category_id', 'payment_tarnsaction'
            ]);

            return response()->json(['data' => $payment]);
        }


    }

    public function generatePayment(Request $request)
    {
        $this->validate($request, [
            'storeAccountNumber' => 'required|min:9',
            'clientAccountNumber' => 'required|min:9',
            'transactionID' => 'required',
            'description' => 'required',
            'amount' => 'required',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
            'terminalCompanyName' => 'required',
        ], [
        ]);


        $trasactionGeneration = new TransactionGeneration();
        $kyc = new PartnerKyc();
//        $checkKyc = $kyc->checkPaymentCliente($request);
        $checkKyc = $kyc->checkPaymentGeneration($request);

        $tokenGeral = '';

        if ($checkKyc) {
            return $checkKyc;
        } else {
            $this->request = $request;

            DB::transaction(function () {

                $store = DB::table('stores')->where('account_number', '=', $this->request->storeAccountNumber)->first();
                $imali = DB::table('imali_accounts')->where('account_number', '=', $this->request->clientAccountNumber)->first();
                $payerUser = DB::table('users')->where('id', $imali->user_id)->first();
                $token = str_replace('Bearer ', '', $this->request->header('authorization'));
                $clientStore = DB::table('user_clients')->where('client_key', $token)->first();

                $user = DB::table('users')->where('id', '=', $imali->user_id)->first();

                $merchant = MerchantAccount::find($store->merchant_account_id);


                $trasactionGeneration = new GenerateToken();
                $tra = new TransactionGeneration();

                $generatedToken = $trasactionGeneration->generatePhoneNumberCode();

                DB::table('payments')->insert([
//                    'transaction_id' => $tra->generateTransaction(),
                    'transaction_id' => $this->request->transactionID,
                    'partner_transaction_id' => $this->request->transactionID,
//                    'store_account_number' => $this->request->storeAccountNumber,
//                    'customer_account_number' => $this->request->clientAccountNumber,
                    'amount' => $this->request->amount,
                    'estado' => 'pending',
                    'status' => 'pending',
                    'description' => $this->request->description,
                    'token' => $generatedToken,
                    'terminalID' => $this->request->terminalID,
                    'terminalChannel' => $this->request->terminalChannel,
                    'terminalCompanyName' => $this->request->terminalCompanyName,
                    'store_id' => $store->id,
                    'merchant_id' => $merchant->id,
                    'client_id' => $clientStore->id,
                    'imali_account_id' => $imali->id,
                    'sender_id' => $imali->user_id,
                    'created_at' => now(),
                    'updated_at' => now(),
                ]);

                $data = ['phone' => $payerUser->phone, 'token' => $generatedToken];

                $this->token = $generatedToken;


                if (env('APP_ENV') == 'production') {
                    $this->smsManager->tokenPayment($data);
                }

            });

            if (env('APP_ENV') == 'local') {
                return response()->json(['message' => trans('otp_sent'), 'otp' => $this->token]);
            } elseif (env('APP_ENV') == 'production') {
                return response()->json(['message' => trans('otp_sent')]);
            }

        }

    }

    public function makePayment(Request $request)
    {
        $this->validate($request, [
            'token' => 'required|min:6',
            'partner_transaction_id' => 'required',
        ], [
            'token.required' => trans('token_required'),
            'partner_transaction_id.required' => trans('partner_transaction_id_required'),
        ]);

        $kyc = new PartnerKyc();
        $checkKyc = $kyc->confirmPayment($request);

        if ($checkKyc) {
            return $checkKyc;
        } else {
            $generatedPayment = Payment::query()->where('partner_transaction_id', '=', $request->partner_transaction_id)->first();

            $this->generatedPayment = $generatedPayment;
            $this->request = $request;

            if ($generatedPayment) {

                DB::transaction(function () {

                    $store = DB::table('stores')->where('id', $this->generatedPayment->store_id)->first();
                    $merchant = DB::table('merchant_accounts')->where('id', $store->merchant_account_id)->first();
                    $imali = DB::table('imali_accounts')->where('user_id', $this->generatedPayment->sender_id)->first();
                    $imaliConfig = DB::table('imali_account_configs')->where('id', $imali->imali_account_config)->first();

                    $valorAPagar = $this->generatedPayment->amount + $imaliConfig->taxa;
                    $points = round($valorAPagar);

                    // Payer or Sender Section
                    DB::table('imali_accounts')->where('user_id', $this->generatedPayment->sender_id)->decrement('balance', $valorAPagar);
                    DB::table('imali_accounts')->where('user_id', $this->generatedPayment->sender_id)->increment('points', $points);

                    $contractoComerciante = DB::table('merchant_contracts')->where('store_id', $this->generatedPayment->store_id)->first();

                    $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                    $valorMin = $contractoComerciante->min_amount;
                    $valorMax = $contractoComerciante->max_amount;

                    if ($taxaDesconto < $valorMin) {
                        $taxaDesconto = $valorMin;
                    }
                    if ($taxaDesconto > $valorMax) {
                        $taxaDesconto = $valorMax;
                    }

//                    $valorFinal = $valorAPagar - $taxaDesconto;
                    $valorFinal = $this->generatedPayment->amount - $taxaDesconto;

                    // Recever User Merchante
//                    DB::table('stores')->where('account_number', $this->generatedPayment->store_account_number)->increment('balance', $valorFinal);


                    if ($merchant) {
                        DB::table('stores')->where('id', $this->generatedPayment->store_id)->increment('balance', $valorFinal);
                        DB::table('merchant_accounts')->where('id', $merchant->id)->increment('balance', $valorFinal);
                    }


//                    DB::table('payments')->insert([
//                        'transaction_id' => $this->generatedPayment->transaction_id,
//                        'partner_transaction_id' => $this->generatedPayment->partner_transaction_id,
//                        'sender_id' => $this->generatedPayment->user_id,
//                        'store_id' => $this->generatedPayment->store_id,
//                        'client_id' => $this->generatedPayment->user_client_id,
//                        'received_points' => $this->generatedPayment->amount,
//                        'amount' => $this->generatedPayment->amount,
//                        'amount_credited' => $valorFinal,
//                        'comissao' => $taxaDesconto,
//                        'description' => $this->generatedPayment->description,
//                        'used_points' => 0,
//                        'estado' => 'pago',
//                        'estado_color' => '#388E3C',
//                        'payment_type' => 'directo',
//                        'terminalID' => $this->generatedPayment->terminalID,
//                        'terminalChannel' => $this->generatedPayment->terminalChannel,
//                        'terminalCompanyName' => $this->generatedPayment->terminalCompanyName,
//                        'created_at' => now(),
//                        'updated_at' => now()
//                    ]);

                    DB::table('payments')
                        ->where('partner_transaction_id', $this->generatedPayment->partner_transaction_id)
                        ->update([
                            'received_points' => $this->generatedPayment->amount,
                            'amount_credited' => $this->generatedPayment->amount - $taxaDesconto,
                            'amount_debited' => $valorAPagar,
                            'comissao' => $taxaDesconto,
                            'description' => $this->generatedPayment->description,
                            'used_points' => 0,
                            'estado' => 'success',
                            'status' => 'success',
                            'estado_color' => '#388E3C',
                            'payment_type' => 'directo',
                            'updated_at' => now()
                        ]);

                    $payerUser = DB::table('users')->where('id', $imali->user_id)->first();

                    $trasactionGeneration = new TransactionGeneration();
                    $transaction = $trasactionGeneration->generateTransaction();

                    $actualPoints = $imali->points + $points;

                    $createTransaction = DB::table('payments')->where('transaction_id', $this->generatedPayment->transaction_id)->first();

                    DB::table('history_payments')->insert([
                        'sender_account' => $imali->account_number,
                        'sender_name' => $payerUser->name,
                        'amount_credited' => $valorFinal,
                        'status_user' => 'sender',
                        'status' => 'done',
                        'comissao' => $taxaDesconto,
                        'amount' => $valorAPagar,
                        'user_id' => $payerUser->id,
                        'actual_points' => $actualPoints,
                        'last_points' => $imali->points,
                        'win_points' => $points,
                        'transaction_id' => $transaction,
                        'payment_id' => $createTransaction->id,
                        'created_at' => now(),
                        'updated_at' => now()
                    ]);

                    DB::table('profits')->insert([
                        'payer_id' => $payerUser->id,
                        'payer_account' => $store->account_number,
                        'amount' => $valorAPagar,
                        'amount_credited' => $valorFinal,
                        'comissao' => $taxaDesconto,
                        'profit_id' => $trasactionGeneration->generateTransaction(),
                        'payment_id' => $createTransaction->id,
                        'profit_payer_id' => $createTransaction->store_id,
                        'created_at' => now(),
                        'updated_at' => now()
                    ]);

//                    DB::table('payment_generations')
//                        ->where('transaction_id', $this->generatedPayment->transaction_id)
//                        ->update(['status' => 'success', 'updated_at' => now()]);
//
//                    DB::table('payment_generation_confirmations')->insert([
//                        'payment_generation_id' => $this->generatedPayment->id,
//                        'payment_id' => $createTransaction->id,
//                        'created_at' => now(),
//                        'updated_at' => now()
//                    ]);

                    $result = json_decode(json_encode($createTransaction), true);

                    if (env('APP_ENV') == 'production') {
                        $this->smsManager->sendMessageToClientePayment($result);
                    }


//                        $sms->sendMessageToComerciante($createTransaction);
//                    $sms->sendMessageToClientePayment($payerUser);
//                        Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
//                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));

                    $log = new Record();

                    $log->createLog([
                        'description' => 'Pagamento na loja do comerciante',
                        'details' => 'Pagamento Feito com Sucesso',
                        'operation' => 'Payment',
                        'properties' => json_encode($createTransaction),
                        'status' => 'Success',
                        'user_id' => $this->generatedPayment->user_id
                    ]);

                }, 5);

            }

        }

        return response()->json(['message' => trans('payment_done')]);
    }

    public function makePaymentOlD(Request $request)
    {
        $this->validate($request, [
            'storeAccountNumber' => 'required|min:9',
            'clientAccountNumber' => 'required|min:9',
            'transactionID' => 'required',
            'amount' => 'required',
            'pin' => 'required|min:4|max:4',
//            'apiKey' => 'required',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
            'description' => 'required',
            'terminalCompanyName' => 'required',
            'usedPoints' => 'required'
        ], [
            'clientAccountNumber.required' => 'O Campo clientAccountNumber é de carácter Obrigatório',
            'storeAccountNumber.required' => 'O Campo storeAccountNumber é de carácter Obrigatório',
            'storeAccountNumber.min' => 'O Campo storeAccountNumber deve ter 9 dígitos',
            'clientAccountNumber.min' => 'O Campo clientAccountNumber deve ter 9 dígitos',
            'transactionID.required' => 'O campo transactionID é obrigatório',
            'pin.required' => 'O pin é obrigatório',
            'pin.max' => 'O pin deve ter 4 digitos',
            'pin.min' => 'O pin deve ter 4 digitos',
            'terminalCompanyName.required' => 'O campo terminalCompanyName é Obrigatório',
            'terminalID.required' => 'terminalID é Obrigatório',
            'amount.required' => 'O Campo amount é obrigatório',
            'apiKey.required' => 'apiKey é obrigatória',
            'description.required' => 'Descrição de Pagamento é obrigatória',
            'usedPoints.required' => 'usedPoints é obrigatória'
        ]);

        $trasactionGeneration = new TransactionGeneration();
        $kyc = new PartnerKyc();
        $checkKyc = $kyc->checkPaymentCliente($request);

        if ($checkKyc) {
            return $checkKyc;
        } else {
            $store = Store::query()->where('account_number', '=', $request->storeAccountNumber)->first();
            $imali = ImaliAccount::query()->where('account_number', '=', $request->clientAccountNumber)->first();
            $payerUser = User::query()->where('id', $imali->user_id)->first();
            $store = Store::query()->where('account_number', $request->storeAccountNumber)->first();
            $token = str_replace('Bearer ', '', $request->header('authorization'));
            $clientStore = UserClient::query()->where('client_key', $token)->first();

            $payer_id = $payerUser->id;
            $imali = ImaliAccount::query()->where('user_id', $payer_id)->first();

            $valorAPagar = $request->amount;
            $points = round($valorAPagar);

            // Payer or Sender Section
            DB::table('imali_accounts')->where('user_id', $payer_id)->decrement('balance', $valorAPagar);
            DB::table('imali_accounts')->where('user_id', $payer_id)->increment('points', $points);

            $contractoComerciante = MerchantContract::query()->where('store_id', $store->id)->first();

            $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

            $valorMin = $contractoComerciante->min_amount;
            $valorMax = $contractoComerciante->max_amount;

            if ($taxaDesconto < $valorMin) {
                $taxaDesconto = $valorMin;
            }
            if ($taxaDesconto > $valorMax) {
                $taxaDesconto = $valorMax;
            }

//                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
            $valorFinal = $valorAPagar - $taxaDesconto;

            // Recever User Merchante
            DB::table('stores')->where('account_number', $store->account_number)->increment('balance', $valorFinal);

//                $profit = $valorAPagar*($contractoComerciante->taxa)/100;

            $transaction = $trasactionGeneration->generateTransaction();

            $createTransaction = Payment::create([
                'transaction_id' => $request->transactionID,
                'sender_id' => $payer_id,
                'store_id' => $store->id,
                'client_id' => $clientStore->id,
                'received_points' => $points,
                'amount' => $valorAPagar,
                'amount_credited' => $valorFinal,
                'comissao' => $taxaDesconto,
                'description' => $request->description,
                'used_points' => $request->usedPoints,
                'estado' => 'pago',
                'estado_color' => '#388E3C',
                'terminalID' => $request->terminalID,
                'terminalChannel' => $request->terminalChannel,
                'terminalCompanyName' => $request->terminalCompanyName,
                'created_at' => now(),
                'updated_at' => now()
            ]);

            $actualPoints = $imali->points + $points;
            $createTransaction->paymentHistoric()->create([
                'sender_account' => $imali->account_number,
                'sender_name' => $payerUser->name,
                'amount_credited' => $valorFinal,
                'status_user' => 'sender',
                'status' => 'done',
                'comissao' => $taxaDesconto,
                'amount' => $valorAPagar,
                'user_id' => $payerUser->id,
                'actual_points' => $actualPoints,
                'last_points' => $imali->points,
                'win_points' => $points,
                'transaction_id' => $transaction
            ]);

            $saveProfit = $createTransaction->profit()->create([
                'payer_id' => $payer_id,
                'payer_account' => $store->account_number,
                'amount' => $valorAPagar,
                'amount_credited' => $valorFinal,
                'comissao' => $taxaDesconto,
                'profit_id' => $trasactionGeneration->generateTransaction(),
                'payment_id' => $createTransaction->id,
                'profit_payer_id' => $createTransaction->store_id
            ]);

            $this->smsManager->sendSMSToComerciante($createTransaction);
//                        $sms->sendMessageToComerciante($createTransaction);
//                    $sms->sendMessageToClientePayment($payerUser);
//                        Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
//                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));

            $log = new Record();
            $log->createLog([
                'description' => $imali->account_number . ' - ' . $store->name,
                'details' => 'Pagamento Feito com Sucesso',
                'operation' => 'Payment',
                'status' => 'Success',
                'user_id' => $request->user()->id
            ]);

            return response()->json(['message' => 'Pagamento Feito com Sucesso!',
//                'transaction' => $transaction,
                'transaction' => $createTransaction->transaction_id,
                'amount' => $createTransaction->amount,
                'created_at' => $createTransaction->created_at,
                'duration' => 3000
            ], 200);

        }

    }

    public function makePayment2(Request $request)
    {
//        $user = User::find($request->user()->id);
        $user = User::query()
            ->join('imali_accounts', 'imali_accounts.user_id', '=', 'users.id')
            ->where('imali_accounts.account_number', '=', $request->account_number)
            ->select('users.*')
            ->first();

        if (Hash::check($request->pin, $user->pin)) {
            $trasactionGeneration = new TransactionGeneration();

//            $payerUser = User::query()->where('user_id', $request->user()->user_id)->first();
            $payerUser = User::query()->where('user_id', $user->user_id)->first();
            $store = Store::query()->where('account_number', $request->store_account_number)->first();
            $payer_id = $payerUser->id;

            $imali = ImaliAccount::query()->where('user_id', $payer_id)->first();
            $kyc = new Kyc();

            $kycCheck = $kyc->checkSenderPayment($request);
            $kyc = new PartnerKyc();
            $checkKYC = $kyc->checkPaymentCliente($request);

            if ($kycCheck) {

                $log = new Record();
                $log->createLog([
                    'description' => $imali->account_number . ' ' . $store->name,
                    'details' => $kycCheck,
                    'operation' => 'Payment',
                    'status' => 'Error',
                    'user_id' => $request->user()->id
                ]);

                return $kycCheck;
            } else {
                if ($payerUser) {
                    if ($imali->balance < $request->amount) {

                        $log = new Record();
                        $log->createLog([
                            'description' => $imali->account_number . ' ' . $store->name,
                            'details' => 'Saldo Insuficiente',
                            'operation' => 'Payment',
                            'status' => 'Error',
                            'user_id' => $request->user()->id
                        ]);

                        return response()->json(['message' => 'Saldo insuficiente', 'class' => 'error'], 402, [], JSON_NUMERIC_CHECK);
                    } else {
                        $valorAPagar = $request->amount;
                        $points = round($valorAPagar);

                        // Payer or Sender Section
                        DB::table('imali_accounts')->where('user_id', $payer_id)->decrement('balance', $valorAPagar);
                        DB::table('imali_accounts')->where('user_id', $payer_id)->increment('points', $points);

                        $contractoComerciante = MerchantContract::query()->where('store_id', $store->id)->first();

                        $taxaDesconto = $valorAPagar * ($contractoComerciante->taxa) / 100;

                        $valorMin = $contractoComerciante->min_amount;
                        $valorMax = $contractoComerciante->max_amount;

                        if ($taxaDesconto < $valorMin) {
                            $taxaDesconto = $valorMin;
                        }
                        if ($taxaDesconto > $valorMax) {
                            $taxaDesconto = $valorMax;
                        }

//                $valorFinal = $valorAPagar - $valorAPagar*($contractoComerciante->taxa)/100;
                        $valorFinal = $valorAPagar - $taxaDesconto;

                        // Recever User Merchante
                        DB::table('stores')->where('account_number', $store->account_number)->increment('balance', $valorFinal);

//                $profit = $valorAPagar*($contractoComerciante->taxa)/100;

                        $transaction = $trasactionGeneration->generateTransaction();

                        $createTransaction = Payment::create([
                            'transaction_id' => $transaction,
                            'sender_id' => $payer_id,
                            'store_id' => $store->id,
                            'received_points' => $points,
                            'amount' => $valorAPagar,
                            'amount_credited' => $valorFinal,
                            'comissao' => $taxaDesconto,
                            'description' => $request->description,
                            'used_points' => $request->used_points,
                            'estado' => 'pago',
                            'estado_color' => '#388E3C',
                            'created_at' => now(),
                            'updated_at' => now()
                        ]);

                        $actualPoints = $imali->points + $points;
                        $createTransaction->paymentHistoric()->create([
                            'sender_account' => $imali->account_number,
                            'sender_name' => $payerUser->name,
                            'amount_credited' => $valorFinal,
                            'status_user' => 'sender',
                            'status' => 'done',
                            'comissao' => $taxaDesconto,
                            'amount' => $valorAPagar,
                            'user_id' => $payerUser->id,
                            'actual_points' => $actualPoints,
                            'last_points' => $imali->points,
                            'win_points' => $points,
                            'transaction_id' => $transaction
                        ]);

                        $saveProfit = $createTransaction->profit()->create([
                            'payer_id' => $payer_id,
                            'payer_account' => $store->account_number,
                            'amount' => $valorAPagar,
                            'amount_credited' => $valorFinal,
                            'comissao' => $taxaDesconto,
                            'profit_id' => $trasactionGeneration->generateTransaction(),
                            'payment_id' => $createTransaction->id,
                            'profit_payer_id' => $createTransaction->store_id
                        ]);
                        if ($saveProfit) {

//                        $sms = new SendSMS();
//                        $sms->sendMessageToClientePayment($createTransaction);
//                        $sms->sendMessageToComerciante($createTransaction);
//                    $sms->sendMessageToClientePayment($payerUser);
//                        Mail::to($store->email)->send(new PagamentoConfirmado($createTransaction));
//                        Mail::to($payerUser->email)->send(new Pagamento($createTransaction));

                            $log = new Record();
                            $log->createLog([
                                'description' => $imali->account_number . ' ' . $store->name,
                                'details' => 'Pagamento Feito com Sucesso',
                                'operation' => 'Payment',
                                'status' => 'Success',
                                'user_id' => $request->user()->id
                            ]);

                            return response()->json(['message' => 'Pagamento Feito com Sucesso!',
                                'transaction' => $transaction,
                                'created_at' => $createTransaction->created_at,
                                'duration' => 3000
                            ], 200);
                        }
                    }
                }
            }
        } else {
            return response()->json(['message' => 'Pin Incorrecto'], 400);
        }
    }

    public function refundCustomerNew(Request $request)
    {
        $this->validate($request, [
            'amount' => 'required',
            'description' => 'required',
            'customerAccountNumber' => 'required',
            'storeAccountNumber' => 'required',
            'paymentTransaction' => 'required',
            'partnerTransactionID' => 'required|min:12',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
            'terminalCompanyName' => 'required',
        ]);

        $kyc = new PartnerKyc();
        $kycCheck = $kyc->checkMerchantRefund($request);

        if ($kycCheck) {
            return $kycCheck;
        } else {
            $this->requestRefund = $request;

            DB::transaction(function () {

                $imaliUser = DB::table('imali_accounts')
                    ->join('users', 'users.id', '=', 'imali_accounts.user_id')
                    ->where('account_number', $this->requestRefund->customerAccountNumber)
                    ->select('users.*', 'imali_accounts.id as imali_account_id')
                    ->first();

                $merchant = DB::table('merchant_accounts')
                    ->join('stores', 'stores.merchant_account_id', '=', 'merchant_accounts.id')
                    ->where('stores.account_number', $this->requestRefund->storeAccountNumber)
                    ->select('merchant_accounts.*', 'stores.balance as store_balance', 'stores.id as store_id')
                    ->first();

                $imaliConfig = DB::table('imali_account_configs')
                    ->where('id', '=', $merchant->kyc_config_id)
                    ->first();

                $loja = Store::query()->where('account_number', '=', $this->requestRefund->storeAccountNumber)->first();

                $payment = Payment::query()
                    ->where('transaction_id', '=', $this->requestRefund->paymentTransaction)
                    ->first();

                $generation = new GenerateToken();

                $token = $generation->generatePhoneNumberCode();

                DB::table('payments')->insert([
//                    'transaction_id' => $this->msid->generateTransaction(),
                    'transaction_id' => $this->requestRefund->partnerTransactionID,
                    'partner_transaction_id' => $this->requestRefund->partnerTransactionID,
                    'amount' => $this->requestRefund->amount,
                    'comissao' => $imaliConfig->taxa_refund_mechant,
                    'amount_debited' => $this->requestRefund->amount + $imaliConfig->taxa_refund_mechant,
                    'amount_credited' => $this->requestRefund->amount,
//                    'account_number' => $this->requestRefund->customerAccountNumber,
                    'description' => $this->requestRefund->description,
                    'store_id' => $merchant->store_id,
                    'sender_id' => $imaliUser->id,
                    'imali_account_id' => $imaliUser->imali_account_id,
                    'payment_id' => $payment->id,
                    'estado' => 'pending',
                    'status' => 'pending',
                    'payment_type' => 'refund',
                    'token' => $token,
                    'merchant_id' => $merchant->id,
                    'client_id' => $this->requestRefund->user()->id,
                    'terminalCompanyName' => $this->requestRefund->terminalCompanyName,
                    'terminalChannel' => $this->requestRefund->terminalChannel,
                    'terminalID' => $this->requestRefund->terminalID,
                    'created_at' => now(),
                    'updated_at' => now()
                ]);

                $data = ['phone' => $merchant->phone_number, 'token' => $token];

                $this->token = $token;

                if (env('APP_ENV') == 'production') {
                    $this->smsManager->tokenPayment($data);
                }
            });

            if (env('APP_ENV') == 'local') {
                return response()->json(['message' => trans('otp_sent'), 'token' => $this->token]);
            } elseif (env('APP_ENV') == 'production') {
                return response()->json(['message' => trans('otp_sent')]);
            }
        }
    }

    public function confirmRefund(Request $request)
    {

        $this->validate($request, [
            'partner_transaction_id' => 'required|min:12',
            'token_otp' => 'required'
        ]);

        $kyc = new PartnerKyc();
        $kycCheck = $kyc->checkConfirmRefund($request);

        if ($kycCheck) {
            return $kycCheck;
        } else {

            $this->requestRefundConfirm = $request;
            DB::transaction(function () {

//                $refund = DB::table('refunds')
//                    ->where('partner_transaction_id', $this->requestRefundConfirm->partner_transaction_id)
//                    ->first();

                $refund = DB::table('payments')
                    ->where('partner_transaction_id', $this->requestRefundConfirm->partner_transaction_id)
                    ->first();

                DB::table('payments')
                    ->where('partner_transaction_id', $this->requestRefundConfirm->partner_transaction_id)
                    ->update([
                        'received_points' => 0,
                        'used_points' => 0,
                        'estado' => 'success',
                        'refund_confirmation' => true,
                        'status' => 'success',
                        'updated_at' => now()
                    ]);

                $merchant = DB::table('merchant_accounts')
                    ->join('stores', 'stores.merchant_account_id', '=', 'merchant_accounts.id')
                    ->where('stores.id', $refund->store_id)
                    ->select('merchant_accounts.*', 'stores.balance as store_balance')
                    ->first();

                $loja = DB::table('stores')->where('id', '=', $refund->store_id)->first();

                $imaliConfig = ImaliAccountConfig::find($merchant->kyc_config_id);

                $payment = DB::table('payments')->where('id', $refund->payment_id)->first();

                $user = DB::table('users')->where('id', $refund->sender_id)->first();
                $imali = DB::table('imali_accounts')->where('user_id', $refund->sender_id)->first();

                DB::table('imali_accounts')->where('user_id', $refund->sender_id)->increment('balance', $refund->amount);
//                DB::table('merchant_accounts')->where('id', $refund->merchant_id)->increment('balance', $refund->amount + $imaliConfig->taxa_refund_mechant);
                DB::table('merchant_accounts')->where('id', $refund->merchant_id)->decrement('balance', $refund->amount + $imaliConfig->taxa_refund_mechant);


                $tran = new TransactionGeneration();

                DB::table('profits')->insert([
                    'payer_id' => $user->id,
                    'payer_account' => $loja->account_number,
                    'amount' => $refund->amount,
                    'amount_credited' => $refund->amount + $imaliConfig->taxa_refund_mechant,
                    'comissao' => $imaliConfig->taxa_refund_mechant,
                    'profit_id' => $tran->generateTransaction(),
                    'payment_id' => $payment->id,
                    'profit_payer_id' => $payment->store_id,
                    'created_at' => now(),
                    'updated_at' => now()
                ]);

//                DB::table('refunds')
//                    ->where('transaction', $refund->transaction)
//                    ->update(['estado' => 'successo', 'updated_at' => now()]);

                $notification = array(
                    'icon' => 'ic_imali_logo_verde_01',
//                            'icon' => 'ic_i_mali_cover',
                    'title' => 'Recebeste ' . $refund->amount . ' MT',
                    'body' => 'Parabéns, ' . ' recebeste reembolso ' . $refund->amount . ' MT ' . ' da loja ' . $loja->name,
                    'click_action' => 'com.imali.payapp.payment_PAGAR_NOTIFICATION',
//                            'color' => '#008577'
                    'color' => '#ffffff'
                );


                $data = array(
                    'transaction' => $refund->transaction_id,
                    'loja' => $loja->name,
                    'loja_account' => $loja->account_number,
                    'pontos' => $payment->received_points,
                    'pontos_usados' => $payment->used_points,
                    'amount' => (double)$refund->amount,
                    'amount_debited' => (double)$refund->amount,
                    'account_number' => (int)$imali->account_number,
                    'phone' => $user->phone,
                    'descricao' => $refund->description,
                    'data' => $refund->created_at,
                    'estado' => $refund->estado,
                    'comissao' => (double)$refund->comissao,
                    'terminal' => 'firebase'
                );

                $result = json_decode(json_encode($payment), true);

                if (env('APP_ENV') == 'production') {
                    $this->smsManager->sendMessageToCustomerPayment($data, $result);
                }

                $this->pushNotifification($user->firebase_token, $notification, $data);

            });
            return response()->json(['message' => trans('refund_done')], 200);
        }
    }

    public function refundCustomer(Request $request)
    {
        $this->validate($request, [
//            'transaction' => 'required',
            'amount' => 'required',
            'description' => 'required',
            'account_number' => 'required',
            'store_account_number' => 'required',
            'payment_transaction' => 'required',
            'partner_transaction_id' => 'required',
//            'password' => 'required',
            'terminalID' => 'required',
            'terminalChannel' => 'required',
            'terminalCompanyName' => 'required',
        ], [
            'transaction.required' => 'O Campo transaction é de carácter Obrigatório',
            'amount.required' => 'O Campo transaction é de carácter Obrigatório',
            'description.required' => 'O campo description é obrigatório',
            'partner_transaction_id.required' => 'O campo partner_transaction_id é obrigatório',
            'account_number.required' => 'O campo account_number é obrigatório',
            'merchant_id.required' => 'O campo merchant_id é obrigatório',
            'imali_user_id.required' => 'O campo imali_user_id é obrigatório',
            'store_id.required' => 'O campo imali_user_id é obrigatório',
            'user_client_id.required' => 'O campo imali_user_id é obrigatório',
        ]);

        $kyc = new PartnerKyc();
        $kycCheck = $kyc->checkMerchantRefund($request);

        if ($kycCheck) {
            return $kycCheck;
        } else {
            $imaliUser = ImaliAccount::query()
                ->join('users', 'users.id', '=', 'imali_accounts.user_id')
                ->where('account_number', $request->account_number)
                ->select('users.*')
                ->first();


            $merchant = MerchantAccount::query()
                ->join('stores', 'stores.merchant_account_id', '=', 'merchant_accounts.id')
                ->where('stores.account_number', $request->store_account_number)
                ->select('merchant_accounts.*', 'stores.balance as store_balance', 'stores.id as store_id')
                ->first();

            $imaliConfig = ImaliAccountConfig::find($merchant->kyc_config_id);
//            $loja = Store::query()->where('id', '=', $request->store_id)->first();
            $loja = Store::query()->where('account_number', '=', $request->store_account_number)->first();

            $payment = Payment::query()
                ->where('transaction_id', $request->payment_transaction)
                ->first();

            $refund = Refund::create([
                'transaction' => $this->msid->generateTransaction(),
                'amount' => $request->amount,
                'fee' => $imaliConfig->taxa_refund_mechant,
                'amount_debited' => $request->amount + $imaliConfig->taxa_refund_mechant,
                'account_number' => $request->account_number,
                'description' => $request->description,
                'store_id' => $merchant->store_id,
                'imali_user_id' => $imaliUser->id,
                'payment_id' => $payment->id,
//                'estado' => 'Reembolso',
                'estado' => 'pendente',
                'merchant_id' => $merchant->id,
                'user_client_id' => $request->user()->id,
                'terminalCompanyName' => $request->terminalCompanyName,
                'terminalChannel' => $request->terminalChannel,
                'terminalID' => $request->terminalID
            ]);

            $payment = Payment::create([
                'transaction_id' => $refund->transaction,
                'sender_id' => $refund->imali_user_id,
                'store_id' => $refund->store_id,
                'received_points' => 0,
                'amount' => $refund->amount,
                'amount_credited' => $refund->amount,
                'comissao' => $refund->fee,
                'description' => $refund->description,
                'used_points' => 0,
                'estado' => 'pago',
                'client_id' => $request->user()->id,
                'payment_type' => 'reembolso',
                'estado_color' => '#388E3C',
                'created_at' => now(),
                'updated_at' => now()
            ]);

            DB::table('imali_accounts')->where('user_id', $refund->imali_user_id)->increment('balance', $refund->amount);
            DB::table('merchant_accounts')->where('id', $refund->merchant_id)->increment('balance', $refund->amount);

            $notification = array(
                'icon' => 'ic_imali_logo_verde_01',
//                            'icon' => 'ic_i_mali_cover',
                'title' => 'Recebeste ' . $request->amount . ' MT',
                'body' => 'Parabéns, ' . ' recebeste reembolso ' . $request->amount . ' MT ' . ' da loja ' . $loja->name,
                'click_action' => 'com.imali.payapp.payment_PAGAR_NOTIFICATION',
//                            'color' => '#008577'
                'color' => '#ffffff'
            );


            $data = array(
                'transaction' => $refund->transaction,
                'loja' => $loja->name,
                'loja_account' => $loja->account_number,
                'pontos' => $payment->received_points,
                'pontos_usados' => $payment->used_points,
                'amount' => (double)$refund->amount,
                'amount_debited' => (double)$refund->amount,
                'account_number' => (int)$refund->account_number,
                'phone' => $request->user()->phone,
                'descricao' => $refund->description,
                'data' => $refund->created_at,
                'estado' => $refund->estado,
                'comissao' => (double)$refund->comissao,
                'terminal' => 'firebase'
            );

            $this->pushNotifification($imaliUser->firebase_token, $notification, $data);

            return response()->json(['message' => 'Reembolso feito com Sucesso!'], 200);
        }
    }

    public function pushNotifification($token, $notification = array(), $data = array())
    {
        $apiKey = 'AAAA8zVzEPQ:APA91bHl_DXB6UGb_6gZlmFnaLTQoANtX_OBjvl3nOy2bSlnFhxedvk6EhGj7cZoIvmlbKeCnqGxXbuyMH_rEPuhRXvuitXzo6Pfl2TMXLar1PlifXqEhYq6tS55UMrY2Kffzj-P_UH-';
        $fields = array('to' => $token, 'notification' => $notification, 'data' => $data);
        $headers = array('Authorization: key=' . $apiKey, 'Content-Type: application/json');
        $url = 'https://fcm.googleapis.com/fcm/send';

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($fields));
        $result = curl_exec($curl);
        curl_close($curl);


        return json_decode($result, true);

    }
}