193 lines
7.4 KiB
PHP
193 lines
7.4 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers;
|
||
|
||
use App\Enums\PaymentTransactionState;
|
||
use App\Models\PaymentTransaction;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Http\Response;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Support\Facades\Lang;
|
||
use Illuminate\Support\Facades\Log;
|
||
use Illuminate\Support\Str;
|
||
use Stripe\StripeClient;
|
||
use Throwable;
|
||
|
||
class StripeController extends Controller
|
||
{
|
||
|
||
private $client;
|
||
private $timeout = 60; //In seconds
|
||
|
||
/**
|
||
* Create a new controller instance.
|
||
*
|
||
* @return void
|
||
*/
|
||
public function __construct()
|
||
{
|
||
// Create a client with a base URI
|
||
$this->client = new StripeClient(config('variables.stripe_secret'));
|
||
|
||
}
|
||
|
||
|
||
public function getMethods()
|
||
{
|
||
$data = $this->client->paymentMethods->all()->toArray();
|
||
return $this->successResponse([
|
||
'hasWebview' => true,
|
||
'methods' => $data,
|
||
]);
|
||
}
|
||
|
||
public function getCheckout($payment_token)
|
||
{
|
||
$transaction = PaymentTransaction::where('payment_token', $payment_token)->first();
|
||
if(empty($transaction)){
|
||
return $this->errorResponse(__('errors.model_not_found', ['model' => 'transaction']), Response::HTTP_NOT_FOUND);
|
||
}
|
||
|
||
$amount = $transaction->amount;
|
||
$receiver = config('variables.receiver_name');
|
||
$receiver_logo = asset('assets/images/logo.jpeg');
|
||
return view('stripe-checkout', compact('amount','receiver','receiver_logo','payment_token'));
|
||
}
|
||
|
||
public function pay(Request $request)
|
||
{
|
||
try {
|
||
|
||
$this->validate($request, [
|
||
'aggregator_id' => 'required|integer',
|
||
'amount' => 'required|numeric|min:5',
|
||
'currency' => 'required|string|size:3',
|
||
'customer_id' => 'required|integer',
|
||
'payment_method' => 'nullable|string',
|
||
'customer_email' => 'required|email',
|
||
'customer_name' => 'required|string',
|
||
'customer_surname' => 'required|string',
|
||
'customer_phone_number' => 'required|string',
|
||
'customer_address' => 'required|string',
|
||
'customer_city' => 'required_if:payment_method,CREDIT_CARD|string',
|
||
'customer_country' => 'required|string|size:2',
|
||
'customer_state' => 'required_if:payment_method,CREDIT_CARD|string|size:2', //Etat du pays dans lequel se trouve le client. Cette valeur est obligatoire si le client se trouve au États Unis d’Amérique (US) ou au Canada (CA)
|
||
'customer_zip_code' => 'required_if:payment_method,CREDIT_CARD|string|size:5',
|
||
'reason' => 'required|string'
|
||
]);
|
||
|
||
$transaction_id = $this->getTransactionID();
|
||
$payment_method = $request->input('payment_method','CREDIT_CARD');
|
||
$amount = $request->input('amount');
|
||
$currency = $request->input('currency');
|
||
|
||
if ($currency != 'USD') {
|
||
// Convertir en multiple de 5
|
||
$amount = $this->roundUpToAny($amount);
|
||
}
|
||
|
||
if($amount < 325 && $currency == 'XAF'){
|
||
$amount = 325;
|
||
}
|
||
|
||
$payment_token = $this->getTransactionToken();
|
||
$payment_url = route('stripe.checkout',['payment_token' =>$payment_token]);
|
||
PaymentTransaction::create([
|
||
'aggregator_id' => $request->input('aggregator_id'),
|
||
"currency" => $request->input('currency'),
|
||
"transaction_id" => $transaction_id,
|
||
"amount" => $amount,
|
||
"payment_method" => $payment_method,
|
||
"payment_token" => $payment_token,
|
||
"payment_url" => $payment_url,
|
||
'state' => PaymentTransactionState::INITIATED,
|
||
"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' => 'Payment initiated',
|
||
'payment_url' => $payment_url
|
||
]);
|
||
|
||
}catch (Throwable $e){
|
||
Log::error($e->getMessage());
|
||
}
|
||
|
||
return $this->errorResponse(trans('errors.unexpected_error'));
|
||
|
||
}
|
||
|
||
public function post(Request $request)
|
||
{
|
||
|
||
$this->validate($request, [
|
||
'payment_token' => 'required|string|exists:payment_transactions,payment_token',
|
||
'stripeToken' => 'required|string',
|
||
]);
|
||
|
||
$token = $request->input('payment_token');
|
||
$transaction = PaymentTransaction::where('payment_token', $token)->where('state', PaymentTransactionState::INITIATED)->firstOrFail();
|
||
|
||
|
||
// Init payment
|
||
$charge = $this->client->charges->create([
|
||
"amount" => round($transaction->amount,2),
|
||
"currency" => $transaction->currency,
|
||
"description" => $transaction->reason,
|
||
// "customer" => 15,
|
||
"source" => $request->input('stripeToken'),
|
||
"receipt_email" => $transaction->customer_email,
|
||
"metadata" => [
|
||
"transaction_id" => $transaction->transaction_id,
|
||
'lang' => app()->getLocale(),
|
||
"customer_id" => $transaction->customer_id,
|
||
"customer_name" => $transaction->customer_name,
|
||
"customer_surname" => $transaction->customer_surname,
|
||
"customer_email" => $transaction->customer_email,
|
||
"customer_phone_number" => $transaction->customer_phone_number,
|
||
"customer_address" => $transaction->customer_address,
|
||
"customer_city" => $transaction->customer_city,
|
||
"customer_country" => $transaction->customer_country,
|
||
"customer_state" => $transaction->customer_state,
|
||
"customer_zip_code" => $transaction->customer_zip_code,
|
||
],
|
||
|
||
]);
|
||
|
||
if($charge){
|
||
|
||
$transaction->update([
|
||
'aggregator_payment_ref' => $charge->id,
|
||
'payment_date' => date('Y-m-d H:i:s', $charge->created) ,
|
||
'state' => PaymentTransactionState::ACCEPTED,
|
||
'payment_method_exact' => $request->input('card_number')
|
||
]);
|
||
|
||
return redirect()->route('checkout',['payment_token' => $token]);
|
||
}
|
||
|
||
session()->flash('error',__('errors.unexpected_error'));
|
||
return redirect()->to(route('stripe.checkout',['payment_token' => $token]));
|
||
}
|
||
|
||
private function getTransactionToken()
|
||
{
|
||
do {
|
||
$code = 'STP-'.Str::random(64);
|
||
$result = collect(DB::select('SELECT * FROM payment_transactions WHERE payment_token = :code', ['code' => $code]));
|
||
$codeCorrect = sizeof($result) < 0;
|
||
} while ($codeCorrect);
|
||
return $code;
|
||
}
|
||
}
|