195 lines
7.1 KiB
PHP
195 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\PaymentMethod;
|
|
use App\Enums\PaymentTransactionStatus;
|
|
use App\Enums\PaymentType;
|
|
use App\Models\Country;
|
|
use App\Models\PaymentAggregator;
|
|
use App\Models\PaymentTransaction;
|
|
use DateTime;
|
|
use GuzzleHttp\Client;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Lang;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Propaganistas\LaravelPhone\PhoneNumber;
|
|
use Propaganistas\LaravelPhone\Rules\Phone;
|
|
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
|
|
use Throwable;
|
|
|
|
class FlutterwaveController extends Controller
|
|
{
|
|
private $timeout = 60; //In seconds
|
|
|
|
/**
|
|
* Create a new controller instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct()
|
|
{
|
|
|
|
}
|
|
|
|
//
|
|
public function pay(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
// 'aggregator_id' => 'required|integer',
|
|
'amount' => 'required|numeric|min:5',
|
|
'currency' => 'required|string|size:3',
|
|
'customer_id' => 'required|integer',
|
|
'customer_email' => 'required|email',
|
|
'customer_name' => 'nullable|string',
|
|
'customer_surname' => 'required|string',
|
|
'customer_phone_number' => 'required|string',
|
|
'customer_address' => 'required|string',
|
|
'reason' => 'required|string'
|
|
]);
|
|
|
|
|
|
$aggregator = PaymentAggregator::where('name','like','%flutterwave%')->firstOrFail();
|
|
|
|
$transaction_id = $this->getTransactionID();
|
|
$amount = $request->input('amount');
|
|
$currency = $request->input('currency');
|
|
|
|
if ($currency != 'USD') {
|
|
// Convertir en multiple de 5
|
|
$amount = $this->roundUpToAny($amount);
|
|
}
|
|
|
|
// Init payment
|
|
$createResponse = (new Client())->post('https://api.flutterwave.com/v3/payments', [
|
|
'headers' => [
|
|
"Authorization" => config('variables.flw_secret_key')
|
|
],
|
|
'json' => [
|
|
"tx_ref" => $transaction_id,
|
|
"amount" => $amount,
|
|
"currency" => $request->input('currency'),
|
|
"redirect_url" => route('flutterwave.webhook'),
|
|
"customer" => [
|
|
"email" => $request->input('customer_email'),
|
|
"phonenumber" => $request->input('customer_phone_number'),
|
|
"name" => $request->input('customer_surname').' '.$request->input('customer_name')
|
|
],
|
|
"customizations" => [
|
|
"title" => $request->input('reason'),
|
|
"logo" => 'https://ilink-app.com/backoffice/images/logo_blueback.png'
|
|
],
|
|
"meta" => [
|
|
"customer_id" => $request->input('customer_id'),
|
|
"customer_address" => $request->input('customer_address')
|
|
]
|
|
],
|
|
'timeout' => $this->timeout
|
|
]);
|
|
|
|
$responseData = json_decode($createResponse->getBody()->getContents());
|
|
$responseCode = $createResponse->getStatusCode();
|
|
|
|
if ($responseCode == 200) {
|
|
|
|
PaymentTransaction::create([
|
|
'aggregator_id' => $aggregator->id,
|
|
"currency" => $request->input('currency'),
|
|
"transaction_id" => $transaction_id,
|
|
"amount" => $amount,
|
|
"payment_method" => "ALL",
|
|
"payment_url" => $responseData->data->link,
|
|
'status' => PaymentTransactionStatus::PENDING,
|
|
"reason" => $request->input('reason'),
|
|
"customer_id" => $request->input('customer_id'),
|
|
"customer_name" => $request->input('customer_name'),
|
|
"customer_surname" => $request->input('customer_surname'),
|
|
"customer_email" => $request->input('customer_email'),
|
|
"customer_phone_number" => $request->input('customer_phone_number'),
|
|
"customer_address" => $request->input('customer_address'),
|
|
"customer_city" => $request->input('customer_city'),
|
|
"customer_country" => $request->input('customer_country'),
|
|
"customer_state" => $request->input('customer_state'),
|
|
"customer_zip_code" => $request->input('customer_zip_code'),
|
|
]);
|
|
|
|
return $this->successResponse([
|
|
'message' => $responseData->message,
|
|
'payment_url' => $responseData->data->link
|
|
], ResponseAlias::HTTP_MOVED_PERMANENTLY);
|
|
|
|
}else{
|
|
return $this->errorResponse($responseData->error->message ?? trans('errors.unexpected_error'),$responseCode);
|
|
}
|
|
}
|
|
|
|
|
|
public function capturePaymentResult(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'transaction_id' => 'nullable|string',
|
|
'tx_ref' => 'nullable|string|exists:payment_transactions,transaction_id',
|
|
'status' => 'nullable|string'
|
|
]);
|
|
|
|
Log::info(json_encode($request->all()));
|
|
if($request->has('tx_ref')){
|
|
$transaction = PaymentTransaction::where('transaction_id',$request->input('tx_ref'))->firstOrFail();
|
|
return $this->getPaymentStatus($transaction, $request->input('transaction_id'));
|
|
}else{
|
|
return response("OK");
|
|
}
|
|
}
|
|
|
|
private function getPaymentStatus(PaymentTransaction $transaction, $flwTransactionId)
|
|
{
|
|
try {
|
|
|
|
// Create a client with a base URI
|
|
$response = (new Client())->get('https://api.flutterwave.com/v3/transactions/'.$flwTransactionId.'/verify', [
|
|
'headers' => [
|
|
"Authorization" => config('variables.flw_secret_key')
|
|
],
|
|
]);
|
|
|
|
$responseData = json_decode($response->getBody()->getContents());
|
|
$responseCode = $response->getStatusCode();
|
|
|
|
if ($responseCode == 200 && $responseData?->data?->status == 'successful'
|
|
&& $responseData?->data?->tx_ref == $transaction->transaction_id) {
|
|
|
|
$transaction->update([
|
|
'status' => PaymentTransactionStatus::ACCEPTED,
|
|
'payment_method_exact' => $responseData?->data?->payment_type ?? null,
|
|
'aggregator_payment_ref' => $responseData?->data?->flw_ref ?? null,
|
|
'payment_date' => $responseData?->data?->created_at != null ? new DateTime($responseData?->data?->created_at) : null,
|
|
]);
|
|
|
|
}
|
|
|
|
} catch (Throwable $e) {
|
|
Log::info("Get Payment Status Error");
|
|
Log::info($e->getMessage());
|
|
$transaction->update([
|
|
'status' => PaymentTransactionStatus::REFUSED
|
|
]);
|
|
|
|
}
|
|
|
|
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
|
|
]);
|
|
}
|
|
|
|
}
|
|
|
|
}
|