<?php
namespace App\Http\Controllers;
use App\Bank\MasterAccount;
use App\Classes\Kyc;
use App\Classes\PushNotification;
use App\Classes\Record;
use App\Classes\TransactionGeneration;
use App\Classes\UserKyc;
use App\Imali\ImaliAccount;
use App\Imali\RechargeImaliAccount;
use App\MobileTariff;
use App\MobileWallet;
use App\User;
use App\WalletFee;
use App\WithdrawalsRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class ThirdPartController extends Controller
{
private function formatMPesaError($response)
{
Log::info('Error Response', [
'content' => $response->json(),
]);
$respObject = $response->json();
return array('message' => $respObject['imaliMessage']);
}
//POST
public function c2bPayment(Request $request)
{
$this->validate(
$request,
[
'phone' => 'required|numeric|digits:9',
'amount' => 'required',
'imaliReference' => 'required'
],
[
'phone.required' => 'Campo Phone é obrigatório',
'phone.numeric' => 'Campo Phone é númerico',
'phone.digits' => 'Campo Phone deve ter 9 digitos',
'amount.required' => 'Campo amount é obrigatório',
'imaliReference.required' => 'Campo imaliReference é obrigatório'
]
);
try {
$user = User::getUserDetails(auth('api')->user()->id);
$userKyc = new UserKyc($user);
// $userKyc = new UserKyc(auth('api')->user()->id);
$usrKycResp = $userKyc->checkUserKYC($request->amount, 404);
if ($usrKycResp->getStatusCode() != 200) return $usrKycResp;
// $response = Http::post('http://localhost:3003/mpesa/c2b-payment', ['phone' => '258' . $request->phone, 'amount' => $request->amount, 'customerAccount' => $request->imaliReference]);
$response = Http::post('http://localhost:3003/mpesa/c2b-payment', ['phone' => '258' . $request->phone, 'amount' => $request->amount, 'customerAccount' => $request->imaliReference]);
//if (($response->status() != 200) && ($response->status() != 201)) return response()->json($response->object(), $response->status());
//if (($response->status() != 200) && ($response->status() != 201)) return response()->json($this->formatMPesaError($response), 404);
if (($response->status() != 200) && ($response->status() != 201)) return response()->json($this->formatMPesaError($response), 404);
if (count($response->json()) > 0 && $response->json()['mpesaCode'] == 'INS-0') {
$imali_account = ImaliAccount::query()->where('user_id', auth('api')->user()->id)->first();
$imali_account_2 = ImaliAccount::query()->where('user_id', auth('api')->user()->id)->first();
$imali_account->balance += $request->amount;
$imali_account->update();
$transactionString = new TransactionGeneration();
$masterAccount = MasterAccount::find(2);
$recharge = RechargeImaliAccount::create([
'imali_account_id' => $imali_account->id,
'transaction_id' => $transactionString->generateTransaction(),
'bank_reference' => $response->json()['mpesaTransactionId'],
'bank_date' => $request->datatransaccao,
'account_reference' => $request->referenciaDoc,
'phone' => $request->phone,
'description' => 'Carregamento realtime via MPesa',
'amount' => $request->amount,
'last_balance' => $imali_account_2->balance,
'balance' => $imali_account->balance,
'recharge_way' => 'MPesa',
'estado' => 'sucesso',
'estado_color' => '#388E3C',
'master_account_id' => $masterAccount->id
]);
$usr = auth('api')->user();
$data = array(
'transaction' => $recharge->transaction_id,
'name' => $usr->name,
'description' => $recharge->description,
'amount' => (float)$recharge->amount,
'phone' => $recharge->phone,
'reference' => $imali_account->reference,
'data' => date($recharge->created_at),
'estado' => $recharge->estado,
'route' => 'RECHARGE_DETAILS',
'recharge_way' => $recharge->recharge_way,
'account_number' => $imali_account->account_number,
'terminal' => 'firebase'
);
$p = new PushNotification(
'Carregamento ' . $recharge->amount . ' MT',
'Parabéns, ' . 'carregaste ' . $recharge->amount . ' MT ' . ' na tua conta ' . $imali_account->account_number,
$usr->firebase_token,
'com.imali.payapp.payment_RECHARGE_DETAILS'
);
$p->sendPush($data);
}
return response()->json(['message' => 'Carregamento enviado com sucesso']);
} catch (\Throwable $th) {
Log::info('Outgoing Response', [
'content' => $th,
]);
return response()->json(['message' => 'Erro ao tentar efectuar o pagamento', 'exception' => $th->getMessage()], 500);
}
}
//POST
public function b2cPayment(Request $request)
{
$this->validate(
$request,
[
'phone' => 'required|numeric|digits:9',
'amount' => 'required',
'mobile_wallets_id' => 'required',
'imaliReference' => 'required'
],
[
'phone.required' => 'Campo Phone é obrigatório',
'phone.numeric' => 'Campo Phone é númerico',
'phone.digits' => 'Campo Phone deve ter 9 digitos',
'amount.required' => 'Campo amount é obrigatório',
'mobile_wallets_id.required' => 'Campo mobile_wallets_id é obrigatório',
'imaliReference.required' => 'Campo imaliReference é obrigatório'
]
);
try {
// $userKyc = new UserKyc(auth('api')->user()->id);
// $usrKycResp = $userKyc->checkUserKYC($request->amount);
// if ($usrKycResp->getStatusCode() != 200) return $usrKycResp;
$b2c_data = $this->checkB2CTransaction(new Request([
'phone' => $request->phone,
'amount' => $request->amount,
'mobile_wallets_id' => $request->mobile_wallets_id,
]));
// return $response;
$usr = auth('api')->user();
//? teste
$kyc = new Kyc();
$request->request->add(['id' => auth()->user()->id, 'receiver_id' => $usr->id]);
$resultKYC = $kyc->checkSender($request);
//? teste
$result = $resultKYC;
if ($result) {
$log = new Record();
$log->createLog([
'description' => 'Transfer Money',
'details' => $result,
'operation' => 'Transfer Money',
'status' => 'Error',
'origin_ip' => $request->ip(),
'properties' => json_encode($request->except(['pin'])),
'origin_request' => $request->url(),
'user_id' => auth()->user()->id
]);
return $result;
}
if (($b2c_data->getStatusCode() != 200)) return $b2c_data;
// $response = Http::post('http://localhost:3003/mpesa/b2c-payment', ['phone' => '258' . $request->phone, 'amount' => $request->amount, 'customerAccount' => $request->imaliReference]);
$response = Http::post('http://localhost:3003/mpesa/b2c-payment', ['phone' => '258' . $request->phone, 'amount' => $request->amount, 'customerAccount' => $request->imaliReference]);
if (($response->status() != 200) && ($response->status() != 201)) return response()->json($this->formatMPesaError($response), $response->status());
//if (($response->status() != 200) && ($response->status() != 201)) return response()->json($response->object(), $response->status());
// if ($response->status() != 201) return response()->json($response->object(), $response->status());
if (count($response->json()) > 0 && $response->json()['mpesaCode'] == 'INS-0') {
$imali_account = ImaliAccount::query()->where('user_id', auth('api')->user()->id)->first();
$new_imali_account = ImaliAccount::query()->where('user_id', auth('api')->user()->id)->first();
//actualizacao do saldo principal
$imali_account->balance = $imali_account->balance - $b2c_data->getData()->total;
$imali_account->update();
$trasactionGeneration = new TransactionGeneration();
$transaction_id = $trasactionGeneration->generateTransaction();
$withdrawalls = WithdrawalsRequest::create([
'imali_account' => $imali_account->account_number,
'account_type' => 'client',
'amount' => $request->amount,
'imali_fee' => $b2c_data->getData()->imali_fee,
'bank_fee' => $b2c_data->getData()->imali_cost,
'description' => 'TRF. MPesa',
'account_number' => $request->phone,
'wallets_id' => 2,
'operators_id' => $request->mobile_wallets_id,
'status' => 'success',
'old_balance' => $new_imali_account->balance,
'new_balance' => $imali_account->balance,
'total' => $b2c_data->getData()->total,
'transaction_id' => $transaction_id,
'commission' => $b2c_data->getData()->commission,
'stamp_tax' => $b2c_data->getData()->stamp_tax,
'user_id' => $imali_account->user_id,
'sender_name' => $usr->name,
'reciever_name' => $b2c_data->getData()->masked_name,
'imali_account_id' => $imali_account->id
]);
// return $response;
// $usr = auth('api')->user();
$data = array(
'transaction' => $withdrawalls->transaction_id,
'name' => $usr->name,
'description' => $withdrawalls->description,
'amount' => (float)$withdrawalls->total,
'phone' => $usr->phone,
'reference' => $imali_account->reference,
'data' => date($withdrawalls->created_at),
'estado' => $withdrawalls->status,
'route' => 'RECHARGE_DETAILS',
'recharge_way' => $withdrawalls->description,
'account_number' => $imali_account->account_number,
'total' => $b2c_data->getData()->total,
'commission' => $b2c_data->getData()->commission,
'stamp_tax' => $b2c_data->getData()->stamp_tax,
'sender_name' => $usr->name,
'reciever_name' => $b2c_data->getData()->masked_name,
'terminal' => 'firebase'
);
$p = new PushNotification(
// 'Transferência de ' . $withdrawalls->amount . ' MT para MPesa',
'Transferência para MPesa',
'Transferência de ' . $withdrawalls->amount . ' MT ' . 'da conta ' . $imali_account->account_number . ' para o MPesa: ' . $request->phone,
$usr->firebase_token,
'com.imali.payapp.payment_RECHARGE_DETAILS'
);
$p->sendPush($data);
// return $response;
}
return response()->json(['message' => 'A tua transferência para MPesa foi efectuada com sucesso!'], 200);
} catch (\Throwable $th) {
Log::info('Outgoing Response', [
'content' => $th,
]);
return response()->json(['message' => 'Erro ao tentar efectuar o pagamento', 'exception' => $th->getMessage()], 500);
}
}
//GET
public function maskedName(Request $request)
{
$this->validate(
$request,
[
'phone' => 'required|numeric|digits:12'
],
[
'phone.required' => 'Campo telefone é obrigatório',
'phone.numeric' => 'Campo telefone é númerico',
'phone.digits' => 'Campo telefone deve ter 12 digitos'
]
);
try {
// $response = Http::get('http://localhost:3003/mpesa/customer-masked-name?phone=' . $request->phone);
$response = Http::get('http://localhost:3003/mpesa/customer-masked-name?phone=' . $request->phone);
// if (($response->status() != 200) && ($response->status() != 201)) return response()->json($response->object(), $response->status());
if (($response->status() != 200) && ($response->status() != 201)) return response()->json($this->formatMPesaError($response), $response->status());
if ($response->json()['mpesaCustomerMaskedName']) {
return response()->json(['name' => $response->json()['mpesaCustomerMaskedName']], $response->status());
}
return response()->json(['name' => 'Indisponivel'], $response->status());
} catch (\Throwable $th) {
Log::info('Outgoing Response', [
'content' => $th,
]);
return response()->json(['message' => 'Erro ao tentar efectuar o pagamento', 'exception' => $th->getMessage()], 500);
}
}
public function checkB2CTransaction(Request $request)
{
$this->validate(
$request,
[
'phone' => 'required|numeric|digits:9',
'mobile_wallets_id' => 'required|numeric',
'amount' => 'required|numeric',
],
[
'amount.required' => 'Campo amount é obrigatório',
'amount.numeric' => 'Campo amount é númerico',
'phone.required' => 'Campo Phone é obrigatório',
'phone.numeric' => 'Campo Phone é númerico',
'phone.digits' => 'Campo Phone deve ter 9 digitos',
'mobile_wallets_id.required' => 'Campo mobile_wallets_id é obrigatório',
'mobile_wallets_id.numeric' => 'Campo mobile_wallets_id é númerico'
]
);
$regex = "/^(82|83|84|85|86|87)+[0-9]{7,7}$/";
if (!preg_match($regex, $request->phone)) return response()->json(['message' => 'Número de telefone inválido'], 400);
$user = User::getUserDetails(auth('api')->user()->id);
$userKyc = new UserKyc($user);
//$userKyc = new UserKyc(auth('api')->user()->id);
$usrKycResp = $userKyc->checkUserKYC($request->amount);
if ($usrKycResp->getStatusCode() != 200) return $usrKycResp;
$mobileTarif = MobileTariff::query()
->where('mobile_wallets_id', $request->mobile_wallets_id)
->where('min', '<=', $request->amount)
->where('max', '>=', $request->amount)
->first();
if (!$mobileTarif) return response()->json(['message' => 'Carteira móvel inválida'], 500);
$mozaFee = WalletFee::query()
->where('wallets_id', 2)
->where('min_amount', '<=', $request->amount)
->where('max_amount', '>=', $request->amount)
->first();
$imali_cost = round(($request->amount * 0.0102), 2);
if ($imali_cost <= $mozaFee->bank_fee) {
$total = $request->amount + $mobileTarif->imali_fee;
$kycRespBalance = $userKyc->checkUserBalance($total);
if ($kycRespBalance->getStatusCode() == 400) return $kycRespBalance;
$maskedNameResponse = $this->maskedName(new Request(['phone' => '258' . $request->phone]));
if ($maskedNameResponse->getStatusCode() != 200) {
$data = [
'phone' => $request->phone,
'amount' => $request->amount,
'total' => $total,
'imali_fee' => $mobileTarif->imali_fee,
'masked_name' => 'Indisponível',
'imali_cost' => $imali_cost,
// 'imali_cost' => $mobileTarif->imali_cost,
'commission' => $mobileTarif->imali_fee - $imali_cost - $mobileTarif->stamp_tax,
'stamp_tax' => $mobileTarif->stamp_tax,
];
return response()->json($data, 200);
}
$maskedName = $maskedNameResponse->getData()->name;
$data = [
'phone' => $request->phone,
'amount' => $request->amount,
'total' => $total,
'imali_fee' => $mobileTarif->imali_fee,
'masked_name' => $maskedName,
// 'imali_cost' => $mobileTarif->imali_cost,
'imali_cost' => $imali_cost,
'commission' => $mobileTarif->imali_fee - $imali_cost - $mobileTarif->stamp_tax,
'stamp_tax' => $mobileTarif->stamp_tax,
];
return response()->json($data, 200);
}
if ($mozaFee->bank_fee <= $imali_cost) {
$total = $request->amount + $mozaFee->imali_fee;
$kycRespBalance = $userKyc->checkUserBalance($total);
if ($kycRespBalance->getStatusCode() == 400) return $kycRespBalance;
$maskedNameResponse = $this->maskedName(new Request(['phone' => '258' . $request->phone]));
if ($maskedNameResponse->getStatusCode() != 200) {
$data = [
'phone' => $request->phone,
'amount' => $request->amount,
'total' => $total,
'imali_fee' => $mozaFee->imali_fee,
'masked_name' => 'Indisponível',
'imali_cost' => $mozaFee->bank_fee,
'commission' => $mozaFee->commission,
'stamp_tax' => $mozaFee->stamp_tax,
];
return response()->json($data, 200);
}
$maskedName = $maskedNameResponse->getData()->name;
$data = [
'phone' => $request->phone,
'amount' => $request->amount,
'total' => $total,
'imali_fee' => $mozaFee->imali_fee,
'masked_name' => $maskedName,
'imali_cost' => $mozaFee->bank_fee,
'commission' => $mozaFee->commission,
'stamp_tax' => $mozaFee->stamp_tax,
];
return response()->json($data, 200);
}
}
}