<?php
namespace App\Traits\PaymentGateway;
use Exception;
use App\Models\User;
use App\Models\UserWallet;
use App\Models\Transaction;
use App\Models\TemporaryData;
use App\Models\UserNotification;
use Illuminate\Support\Facades\DB;
use App\Models\Admin\BasicSettings;
use App\Constants\PaymentGatewayConst;
use App\Models\Admin\PaymentGatewayCurrency;
use Illuminate\Support\Facades\Notification;
use App\Notifications\User\AddMoneyNotification;
trait PaystackGateway {
public function paystackInit($output = null) {
$gateway = new \stdClass();
foreach ($output['gateway']->credentials as $credential) {
if ($credential->name === 'secret-key') {
$gateway->secret_key = $credential->value;
} elseif ($credential->name === 'email') {
$gateway->email = $credential->value;
}
}
$amount = get_amount($output['amount']->total_amount, null, 2) * 100;
$temp_record_token = generate_unique_string('temporary_datas','identifier',60);
$junkData = $this->paystackJunkInsert($output,$temp_record_token);
$url = "https://api.paystack.co/transaction/initialize";
if(get_auth_guard() == 'api'){
$fields = [
'email' => auth()->user()->email,
'amount' => $amount,
'currency' => $output['currency']->code,
'callback_url' => route('api.paystack.pay.callback'). '?output='. $junkData->identifier
];
}else{
$fields = [
'email' => auth()->user()->email,
'amount' => $amount,
'currency' => $output['currency']->code,
'callback_url' => route('paystack.pay.callback'). '?output='. $junkData->identifier
];
}
$fields_string = http_build_query($fields);
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer $gateway->secret_key",
"Cache-Control: no-cache",
));
//So that curl_exec returns the contents of the cURL; rather than echoing it
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//execute post
$result = curl_exec($ch);
$response = json_decode($result);
if($response->status == true) {
if(get_auth_guard() == 'api'){
$response->data = [
'redirect_url' => $response->data->authorization_url,
'redirect_links' => '',
'gateway_type' => PaymentGatewayConst::AUTOMATIC,
'access_code' => $response->data->access_code,
'reference' => $response->data->reference,
];
return $response->data;
}else{
return redirect($response->data->authorization_url)->with('output',$output);
}
} else {
$output['status'] = 'error';
$output['message'] = $response->message;
return back()->with(['error' => [$output['message']]]);
}
}
/**
* function for junk insert
*/
public function paystackJunkInsert($output,$temp_identifier){
$output = $this->output;
$data = [
'gateway' => $output['gateway']->id,
'currency' => $output['currency']->id,
'amount' => json_decode(json_encode($output['amount']),true),
'response' => $output,
'wallet_table' => $output['wallet']->getTable(),
'wallet_id' => $output['wallet']->id,
'creator_table' => auth()->guard(get_auth_guard())->user()->getTable(),
'creator_id' => auth()->guard(get_auth_guard())->user()->id,
'creator_guard' => get_auth_guard(),
];
return TemporaryData::create([
'type' => PaymentGatewayConst::TYPEADDMONEY,
'identifier' => $temp_identifier,
'data' => $data,
]);
}
// function paystack success
function paystackSuccess($request){
$reference = $request['reference'];
$identifier = $request['output'];
$temp_data = TemporaryData::where('identifier',$identifier)->first();
$curl = curl_init();
$secret_key = '';
foreach ($temp_data->data->response->gateway->credentials as $credential) {
if ($credential->name === 'secret-key') {
$secret_key = $credential->value;
break;
}
}
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.paystack.co/transaction/verify/$reference",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"Authorization: Bearer $secret_key",
"Cache-Control: no-cache",
),
));
$result = curl_exec($curl);
$response = json_decode($result);
$responseArray = [
'type' => $temp_data->data->response->type,
'gateway' => $temp_data->data->response->gateway, // Converts the object to an array
'currency' => $temp_data->data->response->currency, // Converts the object to an array
'amount' => $temp_data->data->response->amount, // Converts the object to an array
'form_data' => [
'identifier' => $temp_data->identifier
],
// Assuming this is already an array
'distribute' => $temp_data->data->response->distribute,
'record_handler' => $temp_data->data->response->record_handler,
'capture' => $response->data->reference,
'junk_indentifier' => $identifier
];
if($response->status == true){
try{
$transaction_response = $this->createTransaction($responseArray);
}catch(Exception $e) {
throw new Exception($e->getMessage());
}
return $transaction_response;
}
}
// Update Code (Need to check)
public function createTransaction($output, $temp_remove = true) {
$basic_setting = BasicSettings::first();
$record_handler = $output['record_handler'];
$data = TemporaryData::where('identifier',$output['form_data']['identifier'])->first();
$junk_data = TemporaryData::where('identifier',$output['junk_indentifier'])->first();
$user = User::where('id',$junk_data->data->creator_id)->first();
$inserted_id = $this->$record_handler($output,$status = PaymentGatewayConst::STATUSSUCCESS);
$basic_settings = BasicSettings::first();
if($basic_settings->email_notification == true){
try{
Notification::route('mail',$user->email)->notify(new AddMoneyNotification($inserted_id));
}catch(Exception $e){}
}
$transaction = Transaction::with(['payment_gateway'])->where('id',$inserted_id)->first();
UserNotification::create([
'user_id' => $user->id,
'transaction_id' => $inserted_id,
'details' => [
'title' => 'Add Money using ' . $transaction->payment_gateway->name,
'receiver' => "",
'amount' => get_amount($transaction->request_amount),
'currency' => $transaction->request_currency,
'message' => "Successfully Received."
],
]);
if($temp_remove == true) {
$this->removeTempData($output);
}
if($this->requestIsApiUser()) {
// logout user
$api_user_login_guard = $this->output['api_login_guard'] ?? null;
if($api_user_login_guard != null) {
auth()->guard($api_user_login_guard)->logout();
}
}
}
public function requestIsApiUser() {
$request_source = request()->get('r-source');
if($request_source != null && $request_source == PaymentGatewayConst::APP) return true;
return false;
}
public function insertRecordWeb($output, $status) {
$data = TemporaryData::where('identifier',$output['form_data']['identifier'])->first();
$user = auth()->guard('web')->user();
$user_wallet = UserWallet::where('user_id',$user->id)->first();
$payment_gateway = PaymentGatewayCurrency::where('id',$data->data->currency)->first();
$trx_id = generateTrxString("transactions","trx_id","AM",8);
DB::beginTransaction();
try{
$id = DB::table("transactions")->insertGetId([
'trx_id' => $trx_id,
'type' => $output['type'],
'user_id' => $user->id,
'user_wallet_id' => $data->data->wallet_id,
'payment_gateway_currency_id' => $data->data->currency,
'request_amount' => $data->data->amount->requested_amount,
'fixed_charge' => $data->data->amount->fixed_charge,
'percent_charge' => $data->data->amount->percent_charge,
'total_charge' => $data->data->amount->total_charge,
'total_payable' => $data->data->amount->total_amount,
'request_currency' => $data->data->amount->default_currency,
'available_balance' => $user_wallet->balance + $data->data->amount->will_get,
'payment_currency' => $data->data->amount->sender_cur_code,
'remark' => ucwords(remove_special_char($output['type']," ")) . " With " . $payment_gateway->name,
'details' => json_encode(['gateway_response' => $output['capture']]),
'attribute' => PaymentGatewayConst::RECEIVED,
'status' => $status,
'callback_ref' => $output['callback_ref'] ?? null,
'created_at' => now(),
]);
if($status === PaymentGatewayConst::STATUSSUCCESS) {
$this->updateWalletBalance($user_wallet,$data->data->amount->will_get);
}
DB::commit();
}catch(Exception $e) {
DB::rollBack();
throw new Exception($e->getMessage());
}
return $id;
}
public function updateWalletBalance($user_wallet,$amount) {
$update_amount = $user_wallet->balance + $amount;
$user_wallet->update([
'balance' => $update_amount,
]);
}
public function insertRecordApi($output, $status) {
$data = TemporaryData::where('identifier',$output['form_data']['identifier'])->first();
$junk_data = TemporaryData::where('identifier',$output['junk_indentifier'])->first();
$user = User::where('id',$junk_data->data->creator_id)->first();
$user_wallet = UserWallet::where('user_id',$user->id)->first();
$payment_gateway = PaymentGatewayCurrency::where('id',$data->data->currency)->first();
$trx_id = generateTrxString("transactions","trx_id","SR",8);
DB::beginTransaction();
try{
$id = DB::table("transactions")->insertGetId([
'trx_id' => $trx_id,
'type' => $output['type'],
'user_id' => $user->id,
'user_wallet_id' => $user_wallet->id,
'payment_gateway_currency_id' => $data->data->currency,
'request_amount' => $data->data->amount->requested_amount,
'fixed_charge' => $data->data->amount->fixed_charge,
'percent_charge' => $data->data->amount->percent_charge,
'total_charge' => $data->data->amount->total_charge,
'total_payable' => $data->data->amount->total_amount,
'request_currency' => $data->data->amount->default_currency,
'available_balance' => $user_wallet->balance + $data->data->amount->will_get,
'payment_currency' => $data->data->amount->sender_cur_code,
'remark' => ucwords(remove_special_char($output['type']," ")) . " With " . $payment_gateway->name,
'details' => json_encode(['gateway_response' => $output['capture']]),
'attribute' => PaymentGatewayConst::RECEIVED,
'status' => $status,
'callback_ref' => $output['callback_ref'] ?? null,
'created_at' => now(),
]);
if($status === PaymentGatewayConst::STATUSSUCCESS) {
$this->updateWalletBalance($user_wallet,$data->data->amount->will_get);
}
DB::commit();
}catch(Exception $e) {
DB::rollBack();
throw new Exception($e->getMessage());
}
return $id;
}
public function removeTempData($output) {
try{
$id = $output['tempData']['id'];
TemporaryData::find($id)->delete();
}catch(Exception $e) {
// handle error
}
}
}
?>
Initiates a new payment transaction.
create-order
| Parameter | Type | Details |
|---|---|---|
| amount | decimal | Your Amount , Must be rounded at 2 precision. |
| currency | string | Currency Code, Must be in Upper Case (Alpha-3 code) |
| success_url | string | Enter your return or success URL |
| cancel_url | string (optional) | Enter your cancel or failed URL |
Request Example (guzzle)
<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $base_url.'create-order', [
'headers' => [
'Authorization' => 'Bearer '. $authorizationToken,
'accept' => 'application/json',
'content-type' => 'application/json',
],
'form_params' => [
'amount' => '$amount',
'currency' => 'currency',
'success_url' => 'success_url',
'cancel_url' => 'cancel_url',
],
]);
echo $response->getBody();
**Response: SUCCESS (200 OK)**
{
"message": {
"success": [
"Order created successfully."
]
},
"data": {
"redirect_url":"https://example.com/login/OISADFDFSDFSF",
"order_details":{
"amount" : "10",
"fixed_charge" : 2,
"percent_charge" : 1,
"total_charge" : 3,
"total_payable" : 13,
"currency" : "USD",
"expiry_time": "2024-04-25T06:48:35.984285Z",
"success_url": "http://127.0.0.1/nfcpay/user/transaction/success",
"cancel_url": "http://127.0.0.1/nfcpay/user/transaction/cancel"
}
},
"type": "success"
}
**Response: ERROR (400 FAILED)**
{
"message": {
"error": [
"Invalid token."
]
},
"data": null,
"type": "error"
}