feat: add Ynote payment endpoints and Flutterwave transferts endpoint
This commit is contained in:
parent
5ef2ff4cf4
commit
251578adb9
|
@ -6,6 +6,6 @@ namespace App\Enums;
|
|||
|
||||
abstract class PaymentMethod
|
||||
{
|
||||
const CARD = 'CARD'; // Les remboursements ou recharges vers des clients
|
||||
const WALLET = 'WALLET'; // Les paiements effectués par les clients
|
||||
const CARD = 'CARD';
|
||||
const WALLET = 'WALLET';
|
||||
}
|
||||
|
|
|
@ -12,4 +12,6 @@ abstract class PaymentTransactionStatus
|
|||
const PENDING_OTP = 'PENDING_OTP';
|
||||
const REFUSED = 'REFUSED';
|
||||
const CANCELLED = 'CANCELLED';
|
||||
|
||||
const EXPIRED = 'EXPIRED';
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ class FlutterwaveController extends Controller
|
|||
// Init payment
|
||||
$createResponse = (new Client())->post('https://api.flutterwave.com/v3/payments', [
|
||||
'headers' => [
|
||||
"Authorization" => config('variables.flw_secret_key')
|
||||
"Authorization" => 'Bearer '.config('variables.flw_secret_key')
|
||||
],
|
||||
'json' => [
|
||||
"tx_ref" => $transaction_id,
|
||||
|
@ -232,4 +232,188 @@ class FlutterwaveController extends Controller
|
|||
|
||||
}
|
||||
|
||||
|
||||
public function payOut(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
// 'aggregator_id' => 'required|integer',
|
||||
'amount' => 'required|numeric|min:5',
|
||||
'currency' => 'required|string|size:3',
|
||||
'customer_id' => 'nullable',
|
||||
// 'payment_method' => 'required|string|in:WALLET',
|
||||
'customer_email' => 'required|email',
|
||||
'customer_name' => 'nullable|string',
|
||||
'customer_surname' => 'required|string',
|
||||
'customer_phone_number' => ['nullable','string',(new Phone())->country(['CI','SN','ML','CM','TG','BF','CD','GN','BJ'])],
|
||||
'customer_address' => 'nullable|string',
|
||||
'customer_city' => 'nullable|string',
|
||||
'customer_country' => 'required|string|size:2|in:CI,SN,ML,CM,TG,BF,CD,GN,BJ',
|
||||
'reason' => 'required|string'
|
||||
]);
|
||||
|
||||
$aggregator = PaymentAggregator::where('name','like','%flutterwave%')->firstOrFail();
|
||||
|
||||
try{
|
||||
|
||||
$customer_surname = $request->input('customer_surname');
|
||||
$customer_name = $request->input('customer_name') ?? $customer_surname;
|
||||
$customer_email = $request->input('customer_email');
|
||||
|
||||
$country_code = $request->input('customer_country');
|
||||
$phoneNumber = str_replace(' ','',$request->input('customer_phone_number'));
|
||||
|
||||
$phone = new PhoneNumber($phoneNumber, $country_code);
|
||||
$phoneNumber = str_replace(' ','',$phone->formatInternational());
|
||||
$nationalPhone = str_replace(' ','',$phone->formatNational());
|
||||
$phonePrefix = substr($phoneNumber, 1, strlen($phoneNumber) - strlen($nationalPhone) - 1);
|
||||
|
||||
$amount = $request->input('amount');
|
||||
$payment_method = 'WALLET';
|
||||
|
||||
// if($amount < 500){
|
||||
// return $this->errorResponse('Minimun amount is 500');
|
||||
// }
|
||||
|
||||
|
||||
$transactionId = $this->getTransactionID();
|
||||
|
||||
$transaction = PaymentTransaction::create([
|
||||
'aggregator_id' => $aggregator->id,
|
||||
"currency" => $request->input('currency'),
|
||||
"transaction_id" => $transactionId,
|
||||
"amount" => $amount,
|
||||
"payment_method" => $payment_method,
|
||||
'status' => PaymentTransactionStatus::INITIATED,
|
||||
"reason" => $request->input('reason'),
|
||||
"customer_id" => $request->input('customer_id'),
|
||||
"customer_name" => $customer_name,
|
||||
"customer_surname" => $customer_surname,
|
||||
"customer_email" => $customer_email,
|
||||
"customer_phone_number" => $phoneNumber,
|
||||
"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'),
|
||||
]);
|
||||
|
||||
// Transfert Fund
|
||||
$transfertResponse = (new Client())->post('https://api.flutterwave.com/v3/transfers', [
|
||||
'headers' => [
|
||||
"Authorization" => 'Bearer '.config('variables.flw_secret_key')
|
||||
],
|
||||
'json' => [
|
||||
"account_bank" => 'orangemoney',
|
||||
"account_number" => $nationalPhone,
|
||||
'amount' => $amount,
|
||||
'narration' => $request->input('reason'),
|
||||
'currency' => $request->input('currency'),
|
||||
'reference' => $transactionId,
|
||||
'callback_url' => route('cinetpay.transfert.webhook'),
|
||||
'debit_currency' => $request->input('currency'),
|
||||
],
|
||||
'timeout' => $this->timeout,
|
||||
'http_errors' => false
|
||||
]);
|
||||
|
||||
$responseData = json_decode($transfertResponse->getBody()->getContents());
|
||||
$responseCode = $transfertResponse->getStatusCode();
|
||||
|
||||
if ($responseCode == 200) {
|
||||
|
||||
Log::info("Response of transfert");
|
||||
Log::info(json_encode($responseData));
|
||||
// $transaction->update([
|
||||
// 'aggregator_payment_ref' => $responseData->data[0][0]?->transaction_id,
|
||||
// 'status' => $this->convertTransfertStatus($responseData->data[0][0]?->treatment_status) ,
|
||||
// ]);
|
||||
|
||||
return $this->successResponse([
|
||||
'message' => 'Transfert is pending',
|
||||
'transaction_id' => $transactionId,
|
||||
'transaction_status' => $transaction->status
|
||||
]);
|
||||
}else{
|
||||
Log::error("Error Flutterwave make transfert payment");
|
||||
Log::error(json_encode($responseData));
|
||||
return $this->errorResponse(__('errors.service_unavailable_try_later'));
|
||||
}
|
||||
|
||||
// $errorMessage = $responseData?->description ?? $responseData?->message;
|
||||
|
||||
}catch (Throwable $e){
|
||||
Log::error("Error CinetPay transfert payment");
|
||||
$errorMessage = $e->getMessage();
|
||||
Log::error("Response data :: ".json_encode($responseData ?? ''));
|
||||
Log::error($errorMessage);
|
||||
}
|
||||
|
||||
return $this->errorResponse($errorMessage ?? __('errors.unexpected_error'));
|
||||
}
|
||||
|
||||
public function captureTransfertResult(Request $request)
|
||||
{
|
||||
Log::info("Transfert wevbook");
|
||||
Log::info(json_encode($request->all()));
|
||||
$this->validate($request, [
|
||||
'transaction_id' => 'nullable|string',
|
||||
'client_transaction_id' => 'nullable|string|exists:payment_transactions,transaction_id'
|
||||
]);
|
||||
|
||||
// if($request->has('transaction_id') && $request->has('client_transaction_id')){
|
||||
// $transaction = PaymentTransaction::where('transaction_id',$request->input('client_transaction_id'))->firstOrFail();
|
||||
// try {
|
||||
//
|
||||
// $client = new Client([
|
||||
// 'base_uri' => config('variables.cinetpay_transfert_url')
|
||||
// ]);
|
||||
//
|
||||
// // Login
|
||||
// $loginResponse = $client->post('auth/login', [
|
||||
// 'form_params' => [
|
||||
// "apikey" => config('variables.cinetpay_api_key'),
|
||||
// "password" => config('variables.cinetpay_transfert_password'),
|
||||
// ],
|
||||
// 'timeout' => $this->timeout
|
||||
// ]);
|
||||
//
|
||||
// $responseData = json_decode($loginResponse->getBody()->getContents());
|
||||
// $token = $responseData->data->token;
|
||||
// $responseCode = $loginResponse->getStatusCode();
|
||||
// if ($responseCode == 200 && !empty($token)) {
|
||||
//
|
||||
// $response = $client->get('transfer/check/money', [
|
||||
// 'query' => [
|
||||
// 'token' => $token,
|
||||
// 'transaction_id' => $request->input('transaction_id')
|
||||
// ],
|
||||
// ]);
|
||||
//
|
||||
// $responseData = json_decode($response->getBody()->getContents());
|
||||
// $responseCode = $response->getStatusCode();
|
||||
// if ($responseCode == 200) {
|
||||
//
|
||||
// $transaction->update([
|
||||
// 'aggregator_payment_ref' => $responseData->data[0]?->transaction_id,
|
||||
// 'status' => $this->convertTransfertStatus($responseData->data[0]?->treatment_status),
|
||||
// ]);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } catch (Throwable $e) {
|
||||
// Log::info("Get Cinetpay Transfert Status Error");
|
||||
// $errorMessage = $e->getMessage();
|
||||
// Log::error("Response data :: ".json_encode($responseData ?? ''));
|
||||
// Log::info($errorMessage);
|
||||
// $transaction->update([
|
||||
// 'status' => PaymentTransactionStatus::REFUSED
|
||||
// ]);
|
||||
// }
|
||||
//
|
||||
// return $this->errorResponse($errorMessage ?? __('errors.unexpected_error'));
|
||||
// }else{
|
||||
return response("OK");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,8 @@ class PaymentController extends Controller
|
|||
$networkName = strtolower($request->input('network_name'));
|
||||
|
||||
if(str_contains($networkName,'orange') || str_contains($networkName,'mtn')){
|
||||
return app(CinetpayController::class)->payOut($request);
|
||||
// return app(CinetpayController::class)->payOut($request);
|
||||
return app(FlutterwaveController::class)->payOut($request);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,14 +120,16 @@ class PaymentController extends Controller
|
|||
$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('payment_token','method','amount', 'receiver','receiver_logo'));
|
||||
return view('checkout',compact('paymentEndpoint', 'payment_token','method','amount', 'receiver','receiver_logo'));
|
||||
}
|
||||
|
||||
if($transaction->status == PaymentTransactionStatus::PENDING){
|
||||
return view('verify-payment',compact('transaction_id','method','amount', 'receiver','receiver_logo'));
|
||||
return view('verify-payment',compact('paymentVerifyEndpoint','transaction_id','method','amount', 'receiver','receiver_logo'));
|
||||
}
|
||||
|
||||
$status = $transaction->status == PaymentTransactionStatus::ACCEPTED;
|
||||
|
@ -224,4 +227,28 @@ class PaymentController extends Controller
|
|||
{
|
||||
return app(CinetpayController::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
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\PaymentMethod;
|
||||
use App\Enums\PaymentTransactionStatus;
|
||||
use App\Models\PaymentAggregator;
|
||||
use App\Models\PaymentTransaction;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\HandlerStack;
|
||||
use GuzzleHttp\MessageFormatter;
|
||||
use GuzzleHttp\Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
use Throwable;
|
||||
|
||||
class YnoteOrangeController extends Controller
|
||||
{
|
||||
private $client;
|
||||
private $timeout = 60; //In seconds
|
||||
private $isSyncRequest = false ;// Async request
|
||||
|
||||
private $username = 'iJ7hLnkD8sYddWGV2ZzT7bbsKQMa';
|
||||
private $password = 'gglK1uIj8WGyVUcCEimoI_Cm0o4a';
|
||||
private $channelUserMsisdn = '659923684';
|
||||
private $PIN = '1468';
|
||||
private $X_AUTH_TOKEN = 'WU5PVEVIRUFEOllOT1RFSEVBRDIwMjA=';
|
||||
|
||||
private $baseURL = 'https://api-s1.orange.cm';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Create a client with a base URI
|
||||
$this->client = new Client([
|
||||
'base_uri' => $this->baseURL,
|
||||
'timeout' => $this->timeout,
|
||||
'http_errors' => false,
|
||||
'verify' => false, // Disable SSL Certification verification
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/ynote/methods",
|
||||
* summary="Afficher la liste des methodes de paiment de Ynote",
|
||||
* tags={"Ynote"},
|
||||
* security={{"api_key":{}}},
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="OK",
|
||||
* @OA\JsonContent(
|
||||
* ref="#/components/schemas/ApiResponse",
|
||||
* example = {
|
||||
* "status" : 200,
|
||||
* "response" : {"hasWebview": true, "methods": {"Orange": "Orange"}},
|
||||
* "error":null
|
||||
* }
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
public function getMethods()
|
||||
{
|
||||
return $this->successResponse([
|
||||
'hasWebview' => true,
|
||||
'methods' => [
|
||||
'Orange' => 'Orange'
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Init payment and provide iLink World checkout page to handle payment
|
||||
*/
|
||||
public function initPay(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
// 'aggregator_id' => 'required|integer|exists:payment_aggregators,id',
|
||||
'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',
|
||||
'customer_country' => 'required|string|size:2',
|
||||
'reason' => 'required|string',
|
||||
]);
|
||||
|
||||
$aggregator = PaymentAggregator::where('name','like','%ynote%')->firstOrFail();
|
||||
|
||||
$transaction_id = $this->getTransactionID();
|
||||
$payment_method = 'Orange';
|
||||
$customer_phone_number = $request->input('customer_phone_number');
|
||||
if(str_contains($customer_phone_number,'+237')){
|
||||
$customer_phone_number = substr($customer_phone_number,4);
|
||||
}
|
||||
|
||||
do{
|
||||
$payment_token = Str::random(64);
|
||||
}while(PaymentTransaction::where('payment_token', $payment_token)->exists());
|
||||
|
||||
|
||||
$payment_url = route('checkout',['payment_token' => $payment_token]);
|
||||
|
||||
PaymentTransaction::create([
|
||||
'aggregator_id' => $aggregator->id,
|
||||
"currency" => $request->input('currency'),
|
||||
"transaction_id" => $transaction_id,
|
||||
"amount" => $request->input('amount'),
|
||||
"payment_method" => $payment_method,
|
||||
"payment_url" => $payment_url,
|
||||
'payment_token' => $payment_token,
|
||||
'status' => PaymentTransactionStatus::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" => $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'),
|
||||
"payment_endpoint" => route('ynote.checkoutPay'),
|
||||
"payment_verify_endpoint" => route('ynote.status'),
|
||||
]);
|
||||
|
||||
return $this->successResponse([
|
||||
'message' => 'Payment initiated',
|
||||
'payment_url' => $payment_url
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkoutPay(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'payment_token' => 'required|string|exists:payment_transactions,payment_token',
|
||||
'phone_number' => 'required|string',
|
||||
]);
|
||||
|
||||
$token = $request->input('payment_token');
|
||||
$transaction = PaymentTransaction::where('payment_token', $token)
|
||||
->where('status', PaymentTransactionStatus::INITIATED)->firstOrFail();
|
||||
|
||||
|
||||
$customer_phone_number = $request->input('phone_number');
|
||||
if(str_contains($customer_phone_number,'+237')){
|
||||
$customer_phone_number = substr($customer_phone_number,4);
|
||||
}
|
||||
|
||||
|
||||
// Get Access Token
|
||||
$accessTokenResponse = $this->client->post('/token', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Basic '.base64_encode($this->username.':'.$this->password),
|
||||
],
|
||||
'form_params' => [
|
||||
'grant_type' => 'client_credentials',
|
||||
]
|
||||
]);
|
||||
|
||||
|
||||
$responseBody = json_decode($accessTokenResponse->getBody()->getContents());
|
||||
|
||||
if ($accessTokenResponse->getStatusCode() == 200) {
|
||||
|
||||
$accessToken = $responseBody->access_token;
|
||||
|
||||
// Init Payment
|
||||
$initResponse = $this->client->post('/omcoreapis/1.0.2/mp/init', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer '.$accessToken,
|
||||
'X-AUTH-TOKEN' => $this->X_AUTH_TOKEN
|
||||
],
|
||||
]);
|
||||
|
||||
|
||||
$responseBody = json_decode($initResponse->getBody()->getContents());
|
||||
|
||||
if ($initResponse->getStatusCode() == 200) {
|
||||
|
||||
$payToken = $responseBody->data->payToken;
|
||||
|
||||
// Make Payment
|
||||
$makeResponse = $this->client->post('/omcoreapis/1.0.2/mp/pay', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $accessToken,
|
||||
'X-AUTH-TOKEN' => $this->X_AUTH_TOKEN
|
||||
],
|
||||
'json' => [
|
||||
'notifUrl' => 'http://28f8-102-244-222-34.ngrok-free.app/ynote/webhook' ,// route('ynote.webhook'),
|
||||
'channelUserMsisdn' => $this->channelUserMsisdn,
|
||||
'pin' => $this->PIN,
|
||||
'amount' => ''.intval(ceil(floatval($transaction->amount))),
|
||||
'subscriberMsisdn' => $customer_phone_number,
|
||||
'orderId' => $transaction->transaction_id,
|
||||
'description' => $transaction->reason,
|
||||
'payToken' => $payToken
|
||||
]
|
||||
]);
|
||||
|
||||
$responseBody = json_decode($makeResponse->getBody()->getContents());
|
||||
if ($makeResponse->getStatusCode() == 200) {
|
||||
|
||||
$transaction->update([
|
||||
'aggregator_payment_ref' => $responseBody->data->txnid,
|
||||
'aggregator_payment_token' => $payToken,
|
||||
'status' => strtoupper($responseBody->data->status),
|
||||
"customer_phone_number" => $customer_phone_number,
|
||||
]);
|
||||
|
||||
return redirect()->route('checkout',['payment_token' => $token]);
|
||||
|
||||
|
||||
}else{
|
||||
//If error regenerate transaction id to avoid 'Numero de commande deja utilisé'
|
||||
$transaction->update([
|
||||
'transaction_id' => $this->getTransactionID()
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($responseBody->error)){
|
||||
//Convert into single line
|
||||
session()->flash('error',str_replace(array("\n", "\r"), '',$responseBody->error_description));
|
||||
return redirect()->route('checkout',['payment_token' => $token]);
|
||||
}
|
||||
|
||||
Log::error(json_encode($responseBody));
|
||||
session()->flash('error',__('errors.unexpected_error'));
|
||||
return redirect()->route('checkout',['payment_token' => $token]);
|
||||
}
|
||||
|
||||
public function capturePaymentResult(Request $request)
|
||||
{
|
||||
Log::info("capture");
|
||||
Log::warning(json_encode($request->all()));
|
||||
|
||||
$this->validate($request, [
|
||||
'txnid' => 'required|string'
|
||||
]);
|
||||
|
||||
$transaction = PaymentTransaction::where('aggregator_payment_ref',$request->input('txnid'))->first();
|
||||
return $this->getPaymentStatus($transaction);
|
||||
}
|
||||
|
||||
public function getPaymentStatus(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'transaction_id' => 'required|string|exists:payment_transactions,transaction_id',
|
||||
'verify_btn' => 'nullable|boolean'
|
||||
]);
|
||||
|
||||
$transaction = PaymentTransaction::where('transaction_id',$request->input('transaction_id'))->first();
|
||||
$verify_btn = $request->input('verify_btn');
|
||||
|
||||
try {
|
||||
|
||||
// Si le paiement fait plus de 5 min on l'annule
|
||||
if($transaction->status == PaymentTransactionStatus::PENDING && $transaction->created_at->diffInMinutes(Carbon::now()) > 5){
|
||||
$transaction->update([
|
||||
'status' => PaymentTransactionStatus::CANCELLED
|
||||
]);
|
||||
}
|
||||
|
||||
// Get Access Token
|
||||
$accessTokenResponse = $this->client->post('/token', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Basic '.base64_encode($this->username.':'.$this->password),
|
||||
],
|
||||
'form_params' => [
|
||||
'grant_type' => 'client_credentials',
|
||||
]
|
||||
]);
|
||||
|
||||
$responseBody = json_decode($accessTokenResponse->getBody()->getContents());
|
||||
|
||||
if ($accessTokenResponse->getStatusCode() == 200) {
|
||||
|
||||
$accessToken = $responseBody->access_token;
|
||||
|
||||
$response = $this->client->get('/omcoreapis/1.0.2/mp/paymentstatus/'.$transaction->aggregator_payment_token, [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer '.$accessToken,
|
||||
'X-AUTH-TOKEN' => $this->X_AUTH_TOKEN
|
||||
],
|
||||
]);
|
||||
|
||||
$responseData = json_decode($response->getBody()->getContents());
|
||||
$responseCode = $response->getStatusCode();
|
||||
|
||||
Log::info(json_encode($responseData));
|
||||
Log::info(json_encode($responseCode));
|
||||
Log::info(json_encode([
|
||||
'Authorization' => 'Bearer '.$accessToken,
|
||||
'X-AUTH-TOKEN' => $this->X_AUTH_TOKEN
|
||||
]));
|
||||
|
||||
Log::info(json_encode($transaction->aggregator_payment_token));
|
||||
|
||||
Log::info("Veriication de paement");
|
||||
if ($responseCode == 200) {
|
||||
|
||||
$status = strtoupper($responseData->data->status);
|
||||
if(str_contains($status,'SUCCESS')){
|
||||
$status = PaymentTransactionStatus::ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
$transaction->update([
|
||||
'status' => $status,
|
||||
'payment_date' => $responseData->data->transaction_date ?? null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} catch (Throwable $e) {
|
||||
Log::info("Get Ynote Payment Status Error");
|
||||
Log::info($e);
|
||||
$transaction->update([
|
||||
'status' => PaymentTransactionStatus::REFUSED
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
if($verify_btn){
|
||||
return redirect()->route('checkout',['payment_token' => $transaction->payment_token]);
|
||||
}else {
|
||||
Log::warning($transaction->status);
|
||||
if ($transaction->status == PaymentTransactionStatus::ACCEPTED) {
|
||||
return [
|
||||
'message' => "Payment accepted",
|
||||
'status' => 1,
|
||||
'refresh' => true,
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'message' => "Payment failed",
|
||||
'status' => 0,
|
||||
'refresh' => $transaction->status == PaymentTransactionStatus::PENDING
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -127,6 +127,8 @@ class YoomeeV2Controller extends Controller
|
|||
"customer_country" => $request->input('customer_country'),
|
||||
"customer_state" => $request->input('customer_state'),
|
||||
"customer_zip_code" => $request->input('customer_zip_code'),
|
||||
"payment_endpoint" => route('yoomee.v2.checkoutPay'),
|
||||
"payment_verify_endpoint" => route('yoomee.v2.status'),
|
||||
]);
|
||||
|
||||
return $this->successResponse([
|
||||
|
@ -333,15 +335,11 @@ class YoomeeV2Controller extends Controller
|
|||
$status = strtoupper($responseData->transaction_status);
|
||||
if($status == 'SUCCESS'){
|
||||
$status = PaymentTransactionStatus::ACCEPTED;
|
||||
}else{
|
||||
if(str_starts_with($status,'C')){
|
||||
$status = PaymentTransactionStatus::REFUSED;
|
||||
}
|
||||
}
|
||||
|
||||
$transaction->update([
|
||||
'status' => $status,
|
||||
'payment_date' => $responseData->transaction_date ?? null,
|
||||
'payment_date' => $responseData->data->transaction_date ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -374,27 +372,4 @@ class YoomeeV2Controller extends Controller
|
|||
|
||||
}
|
||||
|
||||
public function merchantRedirect(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
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,9 +54,6 @@ class VerifyCsrfToken {
|
|||
protected function tokensMatch($request) {
|
||||
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
|
||||
|
||||
Log::info($token);
|
||||
Log::error($request->session()->token());
|
||||
|
||||
if (!$token && $header = $request->header('X-XSRF-TOKEN')) {
|
||||
$token = $this->encrypter->decrypt($header);
|
||||
}
|
||||
|
|
|
@ -22,5 +22,7 @@ return [
|
|||
'stripe_secret' => env('STRIPE_SECRET', ''),
|
||||
'stripe_webhook_secret' => env('STRIPE_WEBHOOK_SECRET', ''),
|
||||
'stripe_account' => env('STRIPE_ACCOUNT', ''),
|
||||
'flw_secret_key' => env('FLW_SECRET_KEY', '')
|
||||
'flw_secret_key' => env('FLW_SECRET_KEY', ''),
|
||||
'ynote_username' => env('YNOTE_USERNAME', ''),
|
||||
'ynote_password' => env('YNOTE_PASSWORD', ''),
|
||||
];
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('payment_transactions', function (Blueprint $table) {
|
||||
$table->string('aggregator_payment_token')->after('aggregator_payment_ref')->nullable();
|
||||
$table->string('payment_endpoint')->after('status')->nullable();
|
||||
$table->string('payment_verify_endpoint')->after('payment_endpoint')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('payment_transactions', function (Blueprint $table) {
|
||||
$table->dropColumn(['aggregator_payment_token','payment_endpoint','payment_verify_endpoint']);
|
||||
});
|
||||
}
|
||||
};
|
|
@ -187,7 +187,7 @@
|
|||
</div>
|
||||
<hr class="ml-2 mr-2">
|
||||
<div class="desk-body">
|
||||
<form id="payment_form" name="begin_form" method="POST" action="{{route('yoomee.v2.checkoutPay')}}">
|
||||
<form id="payment_form" name="begin_form" method="POST" action="{{$paymentEndpoint}}">
|
||||
<input type="hidden" name="_token" value="{{ app('request')->session()->get('_token') }}">
|
||||
<input type="hidden" name="payment_token" value="{{ $payment_token }}">
|
||||
<div class="desk-content">
|
||||
|
|
|
@ -213,7 +213,7 @@
|
|||
<div class="desk-action p-3">
|
||||
<div class="row">
|
||||
<div class="col-md-12 pb-2 text-center">
|
||||
<a href="{{route('yoomee.v2.merchantRedirect',['transaction_id' => $transaction_id])}}"
|
||||
<a href="{{route('webPaymentRedirection',['transaction_id' => $transaction_id])}}"
|
||||
class="btn btn-clear btn-block" id="closeCinetPaySeamlessModal">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor"
|
||||
stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"
|
||||
|
|
|
@ -186,7 +186,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<hr class="ml-2 mr-2">
|
||||
<form method="POST" action="{{route('yoomee.v2.verify')}}">
|
||||
<form method="POST" action="{{$paymentVerifyEndpoint}}">
|
||||
<input type="hidden" name="_token" value="{{ app('request')->session()->get('_token') }}">
|
||||
<input type="hidden" name="transaction_id" value="{{ $transaction_id }}">
|
||||
<input type="hidden" name="verify_btn" value="1">
|
||||
|
@ -267,7 +267,7 @@
|
|||
var message = '<a href="" class="btn btn-next btn-block">Vérifier votre paiement <span id="timer"></span></a>';
|
||||
startTimer($countdownDuration, display, '.requestNewCode', message, true);
|
||||
var myHeaders = new Headers();
|
||||
var url = "{{route('yoomee.v2.verify')}}";
|
||||
var url = "{{$paymentVerifyEndpoint}}";
|
||||
var raw = JSON.stringify({
|
||||
"_token" : "{{ app('request')->session()->get('_token') }}",
|
||||
"transaction_id": "{{$transaction_id}}"
|
||||
|
@ -298,7 +298,7 @@
|
|||
} catch (e) {
|
||||
console.log({e});
|
||||
}
|
||||
}, 3000);
|
||||
}, 5000);
|
||||
}
|
||||
)();
|
||||
</script>
|
||||
|
|
|
@ -12,18 +12,34 @@
|
|||
| and give it the Closure to call when that URI is requested.
|
||||
|
|
||||
*/
|
||||
|
||||
$router->get('/', function (){
|
||||
return "yes payment service";
|
||||
});
|
||||
/**
|
||||
* Session endpoints
|
||||
*/
|
||||
$router->group(['middleware' => 'session'], function () use ($router) {
|
||||
|
||||
$router->get('webPaymentRedirection', ['as' => 'webPaymentRedirection', 'uses' => 'PaymentController@webPaymentRedirection']);
|
||||
|
||||
|
||||
// $router->get('/', function (){
|
||||
// return 'Payment Service';
|
||||
// });
|
||||
$router->get('checkout/{payment_token}', ['as' => 'checkout', 'uses' => 'PaymentController@checkout']);
|
||||
$router->post('checkoutPay', ['as' => 'yoomee.v2.checkoutPay', 'uses' => 'YoomeeV2Controller@checkoutPay','middleware' => 'csrf']);
|
||||
$router->post('status', ['as' => 'yoomee.v2.verify', 'uses' => 'YoomeeV2Controller@getPaymentStatus']);
|
||||
$router->get('merchantRedirect', ['as' => 'yoomee.v2.merchantRedirect', 'uses' => 'YoomeeV2Controller@merchantRedirect']);
|
||||
|
||||
/**
|
||||
* Ynote
|
||||
*/
|
||||
$router->group(['prefix' => 'ynote'], function () use ($router) {
|
||||
$router->post('checkoutPay', ['as' => 'ynote.checkoutPay', 'uses' => 'YnoteOrangeController@checkoutPay','middleware' => 'csrf']);
|
||||
$router->post('status', ['as' => 'ynote.status', 'uses' => 'YnoteOrangeController@getPaymentStatus']);
|
||||
$router->get('merchantRedirect', ['as' => 'ynote.merchantRedirect', 'uses' => 'YnoteOrangeController@merchantRedirect']);
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Stripe Endpoints
|
||||
|
@ -42,7 +58,8 @@ $router->addRoute(['GET','POST'],'/cinetpay/webhook', ['as' => 'cinetpay.webhook
|
|||
$router->addRoute(['GET','POST'],'/cinetpay/transfert/webhook', ['as' => 'cinetpay.transfert.webhook' , 'uses' => 'CinetpayController@captureTransfertResult']);
|
||||
$router->addRoute(['GET','POST'],'/stripe/webhook', ['as' => 'stripe.webhook' , 'uses' => 'StripeController@capturePaymentResult']);
|
||||
$router->addRoute(['GET','POST'],'/flutterwave/webhook', ['as' => 'flutterwave.webhook' , 'uses' => 'FlutterwaveController@capturePaymentResult']);
|
||||
|
||||
$router->addRoute(['GET','POST'],'/flutterwave/transfert/webhook', ['as' => 'flutterwave.transfert.webhook' , 'uses' => 'FlutterwaveController@captureTransfertResult']);
|
||||
$router->addRoute(['GET','POST'],'/ynote/webhook', ['as' => 'ynote.webhook' , 'uses' => 'YnoteOrangeController@capturePaymentResult']);
|
||||
|
||||
$router->addRoute(['GET','POST'],'/paymentResult', ['as' => 'paymentResult' , 'uses' => 'PaymentController@paymentResult']);
|
||||
|
||||
|
@ -71,6 +88,17 @@ $router->group(['middleware' => 'auth'], function () use ($router) {
|
|||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Ynote Orange Endpoints
|
||||
*/
|
||||
$router->group(['prefix' => 'ynote'], function () use ($router) {
|
||||
$router->get('methods',['as' => 'ynote.methods', 'uses' => 'YnoteOrangeController@getMethods']);
|
||||
$router->addRoute(['GET','POST'],'pay', ['as' => 'ynote.pay', 'uses' => 'YnoteOrangeController@pay']);
|
||||
$router->addRoute(['GET','POST'],'initPay', ['as' => 'ynote.initPay', 'uses' => 'YnoteOrangeController@initPay']);
|
||||
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Cinetpay Endpoints
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue