260 lines
9.2 KiB
PHP
260 lines
9.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\PaymentMethod;
|
|
use App\Enums\PaymentTransactionStatus;
|
|
use App\Models\Country;
|
|
use App\Models\PaymentAggregator;
|
|
use App\Models\PaymentTransaction;
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Lang;
|
|
use Illuminate\Support\Facades\Log;
|
|
use function Symfony\Component\Translation\t;
|
|
|
|
class PaymentController extends Controller
|
|
{
|
|
public function getMethods(Request $request)
|
|
{
|
|
$aggregator = PaymentAggregator::where('status', 1)->first();
|
|
if (!$aggregator) {
|
|
return $this->errorResponse(trans('errors.model_not_found', ['model' => 'methods']));
|
|
}
|
|
|
|
switch (strtolower($aggregator->name)) {
|
|
case 'yoomee':
|
|
return app(YoomeeController::class)->getMethods();
|
|
case 'yoomeev2':
|
|
return app(YoomeeV2Controller::class)->getMethods();
|
|
case 'cinetpay':
|
|
return app(CinetpayController::class)->getMethods();
|
|
case 'flutterwave':
|
|
return app(FlutterwaveController::class)->getMethods();
|
|
default:
|
|
return $this->errorResponse(__('errors.unexpected_error'));
|
|
}
|
|
}
|
|
|
|
public function pay(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'payment_method' => 'nullable|string',
|
|
'aggregator_id' => 'nullable|integer|exists:payment_aggregators,id',
|
|
]);
|
|
|
|
$payment_method = $request->input('payment_method', PaymentMethod::CARD);
|
|
$aggregator_id = $request->input('aggregator_id');
|
|
|
|
if($aggregator_id){
|
|
$aggregator = PaymentAggregator::findOrFail($aggregator_id);
|
|
}else{
|
|
if($payment_method == PaymentMethod::CARD){
|
|
$aggregator = PaymentAggregator::where('name','like','%stripe%')->firstOrFail();
|
|
}else{
|
|
$aggregator = PaymentAggregator::where('status',1)->firstOrFail();
|
|
}
|
|
}
|
|
|
|
|
|
$data = $request->all();
|
|
$request = new Request();
|
|
$request->merge(array_merge($data,[
|
|
'aggregator_id' => $aggregator->id
|
|
]));
|
|
|
|
switch (strtolower($aggregator->name)) {
|
|
case 'yoomee':
|
|
return app(YoomeeController::class)->pay($request);
|
|
case 'yoomeev2':
|
|
return app(YoomeeV2Controller::class)->initPay($request);
|
|
case 'cinetpay':
|
|
return app(CinetpayController::class)->pay($request);
|
|
case 'flutterwave':
|
|
return app(FlutterwaveController::class)->pay($request);
|
|
case 'stripe':
|
|
return app(StripeController::class)->payIn($request);
|
|
default:
|
|
return $this->errorResponse(__('errors.unexpected_error'));
|
|
}
|
|
}
|
|
|
|
public function payOut(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'network_name' => 'nullable|string',
|
|
'payment_method' => 'required|string|in:WALLET,CARD',
|
|
]);
|
|
|
|
$paymentMethod = $request->input('payment_method');
|
|
|
|
if($paymentMethod === 'WALLET'){
|
|
$networkName = strtolower($request->input('network_name'));
|
|
|
|
if(str_contains($networkName,'orange') || str_contains($networkName,'mtn')){
|
|
// return app(CinetpayController::class)->payOut($request);
|
|
return app(FlutterwaveController::class)->payOut($request);
|
|
}
|
|
}
|
|
|
|
if($paymentMethod == 'CARD'){
|
|
return app(StripeController::class)->payOut($request);
|
|
}
|
|
|
|
|
|
return $this->errorResponse(__('errors.network_not_taken'));
|
|
}
|
|
|
|
public function paymentResult(Request $request)
|
|
{
|
|
$data = $request->all();
|
|
return view('payment-webhook', compact('data'));
|
|
}
|
|
|
|
public function checkout(Request $request, $payment_token)
|
|
{
|
|
$transaction = PaymentTransaction::where('payment_token',$payment_token)->firstOrFail();
|
|
|
|
$transaction_id = $transaction->transaction_id;
|
|
$method = $transaction->payment_method;
|
|
$amount = money($transaction->amount, $transaction->currency)->format(app()->getLocale());
|
|
$receiver = config('variables.receiver_name');
|
|
$receiver_logo = asset('assets/images/logo.jpeg');
|
|
$paymentEndpoint = $transaction->payment_endpoint;
|
|
$paymentVerifyEndpoint = $transaction->payment_verify_endpoint;
|
|
|
|
|
|
if($transaction->status == PaymentTransactionStatus::INITIATED){
|
|
return view('checkout',compact('paymentEndpoint', 'payment_token','method','amount', 'receiver','receiver_logo'));
|
|
}
|
|
|
|
if($transaction->status == PaymentTransactionStatus::PENDING){
|
|
return view('verify-payment',compact('paymentVerifyEndpoint','transaction_id','method','amount', 'receiver','receiver_logo'));
|
|
}
|
|
|
|
$status = $transaction->status == PaymentTransactionStatus::ACCEPTED;
|
|
|
|
|
|
return view('payment-status',compact('transaction_id','method','amount', 'receiver','receiver_logo','status'));
|
|
}
|
|
|
|
|
|
public function checkStatus(Request $request, $transaction_id)
|
|
{
|
|
$transaction = PaymentTransaction::where('transaction_id',$transaction_id)->firstOrFail();
|
|
|
|
if($transaction->status == PaymentTransactionStatus::ACCEPTED){
|
|
return $this->successResponse([
|
|
'message' => 'Payment Accepted',
|
|
'transaction_id' => $transaction->transaction_id,
|
|
'status' => $transaction->status
|
|
]);
|
|
|
|
}else{
|
|
|
|
return $this->errorResponse([
|
|
'message' => 'Payment '.$transaction->status,
|
|
'status' => $transaction->status
|
|
]);
|
|
}
|
|
|
|
}
|
|
|
|
public function getFees(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'amount' => 'required|numeric|min:0',
|
|
'country_id' => 'required|integer|exists:countries,id',
|
|
'payment_type' => 'required|string|in:CASH_IN,CASH_OUT',
|
|
'payment_method' => 'required|string|in:CARD,WALLET',
|
|
'payment_channel' => 'nullable|string',
|
|
]);
|
|
|
|
$fees = 0;
|
|
|
|
$amount = $request->input('amount');
|
|
$paymentChannel = $request->input('payment_channel');
|
|
$paymentMethod = $request->input('payment_method');
|
|
$paymentType = $request->input('payment_type');
|
|
$countryId = $request->input('country_id');
|
|
$country = Country::where('id', $countryId)->firstOrFail();
|
|
$countryCode = $country->code_country;
|
|
|
|
|
|
if($paymentMethod == PaymentMethod::CARD){
|
|
$aggregator = PaymentAggregator::where('name','like','%stripe%')->first();
|
|
}
|
|
|
|
if($paymentMethod == PaymentMethod::WALLET){
|
|
$aggregator = PaymentAggregator::where('status',1)->first();
|
|
}
|
|
|
|
if(!empty($aggregator)){
|
|
$baseQuery = $aggregator->rates()->where('type', $paymentType)
|
|
->where('method', $paymentMethod)
|
|
->when($paymentChannel, function ($q) use($paymentChannel){
|
|
return $q->where('channel',$paymentChannel);
|
|
});
|
|
|
|
$rate = (clone $baseQuery)->where('country', $countryCode)->first();
|
|
if(empty($rate)){
|
|
$rate = (clone $baseQuery)->where('country','ALL')->first();
|
|
}
|
|
|
|
|
|
if(!empty($rate)){
|
|
if(!empty($rate->fixed_fees)){
|
|
$targetCurrency = $country->currency->code;
|
|
$sourceCurrency = $targetCurrency;
|
|
if(!empty($rate->fixed_fees_currency)){
|
|
$sourceCurrency = $rate->fixed_fees_currency;
|
|
}
|
|
$fixed_fees = $this->toMoneyAmount($rate->fixed_fees, $sourceCurrency, $targetCurrency);
|
|
$fees = (($amount - $fixed_fees) * $rate->rate / 100 ) + $fixed_fees;
|
|
}else{
|
|
$fees = $amount * $rate->rate / 100;
|
|
}
|
|
}
|
|
|
|
return $this->successResponse(['fees' => round($fees, 2)]);
|
|
}else {
|
|
Log::error("Aggregateur non disponible");
|
|
return $this->errorResponse(__('errors.service_unavailable_try_later'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws GuzzleException
|
|
*/
|
|
public function checkBalance(Request $request)
|
|
{
|
|
// return app(CinetpayController::class)->checkBalance($request);
|
|
return app(FlutterwaveController::class)->checkBalance($request);
|
|
}
|
|
|
|
|
|
public function webPaymentRedirection(Request $request)
|
|
{
|
|
|
|
$this->validate($request, [
|
|
'transaction_id' => 'required|string|exists:payment_transactions,transaction_id'
|
|
]);
|
|
|
|
$transaction = PaymentTransaction::where('transaction_id',$request->input('transaction_id'))->first();
|
|
|
|
if ($transaction->status == PaymentTransactionStatus::ACCEPTED) {
|
|
return redirect()->route('paymentResult', [
|
|
'transaction_id' => $transaction->transaction_id,
|
|
'token' => $transaction->payment_token,
|
|
'status' => 1
|
|
]);
|
|
} else {
|
|
return redirect()->route('paymentResult', [
|
|
'message' => "Payment failed",
|
|
'status' => 0
|
|
]);
|
|
}
|
|
}
|
|
}
|