diff --git a/system/uploads/paymentgateway/BankStkPush.php b/system/uploads/paymentgateway/BankStkPush.php new file mode 100644 index 0000000..1c3347d --- /dev/null +++ b/system/uploads/paymentgateway/BankStkPush.php @@ -0,0 +1,205 @@ +assign('_title', 'Bank Stk Push - ' . $config['CompanyName']); + $ui->display('bankstkpush.tpl'); +} + +function BankStkPush_save_config() +{ + global $admin, $_L; + $bankacc = _post('account'); + $bankname = _post('bankname'); + $d = ORM::for_table('tbl_appconfig')->where('setting', 'Stkbankacc')->find_one(); + if ($d) { + $d->value = $bankacc; + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = 'Stkbankacc'; + $d->value = $bankacc; + $d->save(); + } + $d = ORM::for_table('tbl_appconfig')->where('setting', 'Stkbankname')->find_one(); + if ($d) { + $d->value = $bankname; + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = 'Stkbankname'; + $d->value = $bankname; + $d->save(); + } + + _log('[' . $admin['username'] . ']: Stk Bank details ' . $_L['Settings_Saved_Successfully'], 'Admin', $admin['id']); + + r2(U . 'paymentgateway/BankStkPush', 's', $_L['Settings_Saved_Successfully']); +} + + +function BankStkPush_create_transaction($trx, $user ) +{ + $url=(U. "plugin/initiatebankstk"); + + $d = ORM::for_table('tbl_payment_gateway') + ->where('username', $user['username']) + ->where('status', 1) + ->find_one(); + $d->gateway_trx_id = ''; + $d->payment_method = 'Bank Stk Push'; + $d->pg_url_payment = $url; + $d->pg_request = ''; + $d->expired_date = date('Y-m-d H:i:s', strtotime("+5 minutes")); + $d->save(); + + r2(U . "order/view/" . $d['id'], 's', Lang::T("Create Transaction Success, Please click pay now to process payment")); + + die(); +} + +function BankStkPush_payment_notification() +{ + $captureLogs = file_get_contents("php://input"); + + $analizzare = json_decode($captureLogs); + /// sleep(10); + file_put_contents('back.log',$captureLogs,FILE_APPEND); + $response_code = $analizzare->Body->stkCallback->ResultCode; + $resultDesc = ($analizzare->Body->stkCallback->ResultDesc); + $merchant_req_id = ($analizzare->Body->stkCallback->MerchantRequestID); + $checkout_req_id = ($analizzare->Body->stkCallback->CheckoutRequestID); + + $amount_paid = ($analizzare->Body->stkCallback->CallbackMetadata->Item['0']->Value);//get the amount value + $mpesa_code = ($analizzare->Body->stkCallback->CallbackMetadata->Item['1']->Value);//mpesa transaction code.. + $sender_phone = ($analizzare->Body->stkCallback->CallbackMetadata->Item['4']->Value);//Telephone Number + + $PaymentGatewayRecord = ORM::for_table('tbl_payment_gateway') + ->where('checkout', $checkout_req_id) + ->where('status', 1) // Add this line to filter by status + ->order_by_desc('id') + ->find_one(); + + $uname=$PaymentGatewayRecord->username; + $plan_id=$PaymentGatewayRecord->plan_id; + $mac_address=$PaymentGatewayRecord->mac_address; + $user=$PaymentGatewayRecord; + + $userid = ORM::for_table('tbl_customers') + ->where('username', $uname) + ->order_by_desc('id') + ->find_one(); + + $userid->username=$uname; + $userid->save(); + $plans = ORM::for_table('tbl_plans') + ->where('id', $plan_id) + + ->order_by_desc('id') + ->find_one(); + + if ($response_code=="1032") + { + $now = date('Y-m-d H:i:s'); + $PaymentGatewayRecord->paid_date = $now; + $PaymentGatewayRecord->status = 4; + $PaymentGatewayRecord->save(); + + exit(); + } + if($response_code=="1037"){ + $PaymentGatewayRecord->status = 1; + $PaymentGatewayRecord->pg_paid_response = 'User failed to enter pin'; + $PaymentGatewayRecord->save(); + + exit(); + } + + if($response_code=="1"){ + $PaymentGatewayRecord->status = 1; + $PaymentGatewayRecord->pg_paid_response = 'Not enough balance'; + $PaymentGatewayRecord->save(); + + exit(); + } + + if($response_code=="2001"){ + $PaymentGatewayRecord->status = 1; + $PaymentGatewayRecord->pg_paid_response = 'Wrong Mpesa pin'; + $PaymentGatewayRecord->save(); + + exit(); + } + + if($response_code=="0"){ + + $now = date('Y-m-d H:i:s'); + $date = date('Y-m-d'); + $time= date('H:i:s'); + + $check_mpesa = ORM::for_table('tbl_payment_gateway') + ->where('gateway_trx_id', $mpesa_code) + ->find_one(); + + if($check_mpesa){ + echo "double callback, ignore one"; + + die; + } + + $plan_type=$plans->type; + $UserId=$userid->id; + + if (!Package::rechargeUser($UserId, $user['routers'], $user['plan_id'], $user['gateway'], $mpesa_code)){ + $PaymentGatewayRecord->status = 2; + $PaymentGatewayRecord->paid_date = $now; + $PaymentGatewayRecord->gateway_trx_id = $mpesa_code; + $PaymentGatewayRecord->save(); + $username = $PaymentGatewayRecord->username; + + // Check if a transaction with the same gateway_trx_id already exists + $existingTransaction = ORM::for_table('tbl_transactions') + ->where('mpesacode', $mpesa_code) + ->find_one(); + + if (!$existingTransaction) { + // Save transaction data to tbl_transactions + $transaction = ORM::for_table('tbl_transactions')->create(); + $transaction->invoice = $PaymentGatewayRecord->gateway_trx_id; // Set invoice to gateway_trx_id value + $transaction->username = $PaymentGatewayRecord->username; + $transaction->plan_name = $PaymentGatewayRecord->plan_name; + $transaction->price = $amount_paid; + $transaction->recharged_on = $date; + $transaction->recharged_time = $time; + $transaction->expiration = $now; + $transaction->time = $now; + $transaction->method = $PaymentGatewayRecord->payment_method; + $transaction->routers = 0; + $transaction->Type = 'Balance'; + $transaction->mpesacode = $mpesa_code; + $transaction->save(); + } else { + error_log("Duplicate transaction entry detected for gateway_trx_id: " . $PaymentGatewayRecord->gateway_trx_id); + } + } else { + // Update tbl_recharges + $PaymentGatewayRecord->status = 2; + $PaymentGatewayRecord->paid_date = $now; + $PaymentGatewayRecord->gateway_trx_id = $mpesa_code; + $PaymentGatewayRecord->save(); + } + + + } +} diff --git a/system/uploads/paymentgateway/flutterwave.php b/system/uploads/paymentgateway/flutterwave.php new file mode 100644 index 0000000..7754b49 --- /dev/null +++ b/system/uploads/paymentgateway/flutterwave.php @@ -0,0 +1,234 @@ +assign('_title', 'Flutterwave - Payment Gateway'); + $ui->assign('cur', json_decode(file_get_contents('system/paymentgateway/flutterwave_currency.json'), true)); + $ui->assign('channel', json_decode(file_get_contents('system/paymentgateway/flutterwave_channel.json'), true)); + $ui->display('flutterwave.tpl'); + } + + + function flutterwave_save_config() + { + global $admin, $_L; + $flutterwave_secret_key = _post('flutterwave_secret_key'); + $flutterwave_currency = _post('flutterwave_currency'); + $d = ORM::for_table('tbl_appconfig')->where('setting', 'flutterwave_secret_key')->find_one(); + if ($d) { + $d->value = $flutterwave_secret_key; + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = 'flutterwave_secret_key'; + $d->value = $flutterwave_secret_key; + $d->save(); + } + $d = ORM::for_table('tbl_appconfig')->where('setting', 'flutterwave_currency')->find_one(); + if ($d) { + $d->value = $flutterwave_currency; + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = 'flutterwave_currency'; + $d->value = $flutterwave_currency; + $d->save(); + } + $d = ORM::for_table('tbl_appconfig')->where('setting', 'flutterwave_channel')->find_one(); + if ($d) { + $d->value = implode(',', $_POST['flutterwave_channel']); + $d->save(); + } else { + $d = ORM::for_table('tbl_appconfig')->create(); + $d->setting = 'flutterwave_channel'; + $d->value = implode(',', $_POST['flutterwave_channel']); + $d->save(); + } + _log('[' . $admin['username'] . ']: Flutterwave ' . $_L['Settings_Saved_Successfully'], 'Admin', $admin['id']); + + r2(U . 'paymentgateway/flutterwave', 's', $_L['Settings_Saved_Successfully']); + } + +function flutterwave_create_transaction($trx, $user) +{ + global $config; + $txref = uniqid('trx'); + $json = [ + 'tx_ref' => $txref, + 'amount' => $trx['price'], + 'currency' => $config['flutterwave_currency'], + 'payment_options' => explode(',', $config['flutterwave_channel']), + 'customer' => [ + 'email' => (empty($user['email'])) ? $user['username'] . '@' . $_SERVER['HTTP_HOST'] : $user['email'], + 'name' => $user['fullname'], + 'phonenumber' => $user['phonenumber'] + ], + 'meta' => [ + 'price' => $trx['price'], + 'username' => $user['username'], + 'trxid' => $trx['id'] + ], + + 'customizations' => [ + 'title' => $trx['plan_name'], + 'description' => $trx['plan_name'], + ], + + 'redirect_url' => U . 'callback/flutterwave' + ]; + // die(json_encode($json,JSON_PRETTY_PRINT)); + + $result = json_decode(Http::postJsonData(flutterwave_get_server() . 'payments', $json,[ + 'Authorization: Bearer ' . $config['flutterwave_secret_key'], + 'Cache-Control: no-cahe' + ], + ), +true); + +//die(json_encode($result,JSON_PRETTY_PRINT)); + +if ($result['status'] == 'error') { + Message::sendTelegram("Flutterwave payment failed\n\n" . json_encode($result, JSON_PRETTY_PRINT)); + r2(U . 'order/package', 'e', Lang::T("Failed to create transaction.\n".$result['message'])); + } + $d = ORM::for_table('tbl_payment_gateway') + ->where('username', $user['username']) + ->where('status', 1) + ->find_one(); + $d->gateway_trx_id = $txref; + $d->pg_url_payment = $result['data']['link']; + $d->pg_request = json_encode($result); + $d->expired_date = date('Y-m-d H:i:s', strtotime("+ 6 HOUR")); + $d->save(); + + header('Location: ' . $result['data']['link']); + exit(); + + r2(U . "order/view/" . $d['id'], 's', Lang::T("Create Transaction Success")); + + +} + +function flutterwave_payment_notification() +{ + global $config; +if(isset($_GET['status'])) + + { + //* check payment status + if($_GET['status'] == 'cancelled') + { + // die(json_encode($txref,JSON_PRETTY_PRINT)); + Message::sendTelegram("Flutterwave Payment Cancelled: \n\n"); + r2(U . 'order/package', 'e', Lang::T("Flutterwave Payment Cancelled.")); + } + elseif($_GET['status'] == 'successful') + { + + $txid = $_GET['transaction_id']; + $result = json_decode(Http::getData(flutterwave_get_server() . 'transactions/' . $txid. '/verify', [ + 'Authorization: Bearer ' . $config['flutterwave_secret_key'], + 'Cache-Control: no-cahe' + ]), true); + //die(json_encode($result,JSON_PRETTY_PRINT)); + { + $id = $result['data']['id']; + $amountPaid = $result['data']['charged_amount']; + $amountToPay = $result['data']['meta']['price']; + $username = $result['data']['meta']['username']; + $trxid = $result['data']['meta']['trxid']; + if($amountPaid >= $amountToPay) + { + // die(json_encode($trxid,JSON_PRETTY_PRINT)); + // echo 'Payment successful'; + $d = ORM::for_table('tbl_payment_gateway') + ->where('username', $username) + ->where('status', 1) + ->find_one(); + $d->gateway_trx_id = $id; + $d->save(); + r2(U . 'order/view/'.$trxid.'/check'); + // r2(U . 'order/package', 's', Lang::T("Flutterwave Payment Completed.")); + exit(); + //* Continue to give item to the user + } + else + { + // echo 'Fraud transactio detected'; + r2(U . 'order/package', 'e', Lang::T("Fraud transactions detected.")); + exit(); + } + } + } + } + } + + + function flutterwave_get_status($trx, $user) + { + global $config; + $trans_id = $trx['gateway_trx_id']; + $result = json_decode(Http::getData(flutterwave_get_server() . 'transactions/' . $trx['gateway_trx_id']. '/verify', [ + 'Authorization: Bearer ' . $config['flutterwave_secret_key'], + 'Cache-Control: no-cahe' + ]), true); + //die(json_encode($result,JSON_PRETTY_PRINT)); + if ($result['status'] == 'error') { + r2(U . "order/view/" . $trx['id'], 'w', Lang::T("Transaction still unpaid.")); + } else if (in_array($result['status'], ['success']) && $trx['status'] != 2) { + if (!Package::rechargeUser($user['id'], $trx['routers'], $trx['plan_id'], $trx['gateway'], 'Flutterwave')) { + r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Failed to activate your Package, please try again later.")); + } + $trx->pg_paid_response = json_encode($result); + $trx->payment_method = 'Flutterwave'; + $trx->payment_channel = $result['data']['payment_type']; + $trx->paid_date = date('Y-m-d H:i:s', strtotime( $result['data']['created_at'])); + $trx->status = 2; + $trx->save(); + + r2(U . "order/view/" . $trx['id'], 's', Lang::T("Transaction successful.")); + } else if ($result['status'] == 'EXPIRED') { + $trx->pg_paid_response = json_encode($result); + $trx->status = 3; + $trx->save(); + r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Transaction expired.")); + } else if ($trx['status'] == 2) { + r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Transaction has been paid..")); + }else{ + Message::sendTelegram("flutterwave_get_status: unknown result\n\n".json_encode($result, JSON_PRETTY_PRINT)); + r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Unknown Command.")); + } + + } + + +function flutterwave_get_server() +{ + global $_app_stage; + if ($_app_stage == 'Live') { + return 'https://api.flutterwave.com/v3/'; + } else { + return 'https://api.flutterwave.com/v3/'; + } +} diff --git a/system/uploads/paymentgateway/flutterwave_channel.json b/system/uploads/paymentgateway/flutterwave_channel.json new file mode 100644 index 0000000..09e38c1 --- /dev/null +++ b/system/uploads/paymentgateway/flutterwave_channel.json @@ -0,0 +1,35 @@ +[ + + { + "id": "card", + "name": "Card Payment" + }, + { + "id": "ussd", + "name": "USSD" + }, + { + "id": "account", + "name": "Bank Account" + }, + { + "id": "banktransfer", + "name": "Bank Transfer" + }, + { + "id": "nqr", + "name": "QR payment" + }, + { + "id": "mpesa", + "name": "M-Pesa" + }, + { + "id": "mobilemoneyghana", + "name": "Mobile money Ghana" + }, + { + "id": "credit", + "name": "Credit payment" + } +] diff --git a/system/uploads/paymentgateway/flutterwave_currency.json b/system/uploads/paymentgateway/flutterwave_currency.json new file mode 100644 index 0000000..fe716ea --- /dev/null +++ b/system/uploads/paymentgateway/flutterwave_currency.json @@ -0,0 +1,30 @@ +[ + { + "id": "NGN", + "name": "Nigerian Naira" + }, + { + "id": "GHC", + "name": "Ghana Cedis" + }, + { + "id": "KES", + "name": "Kenyan Shilling" + }, + { + "id": "ZAR", + "name": "South African Rand" + }, + { + "id": "GBP", + "name": "British Pound Sterling" + }, + { + "id": "USD", + "name": "United States Dollar" + }, + { + "id": "TZS", + "name": "Tanzanian Shilling" + } +] diff --git a/system/uploads/paymentgateway/index.html b/system/uploads/paymentgateway/index.html new file mode 100644 index 0000000..06d7405 Binary files /dev/null and b/system/uploads/paymentgateway/index.html differ