Log files added by Sriram R for Payment logs track
This commit is contained in:
parent
e420e651db
commit
bca9ba3ca5
@ -18,8 +18,7 @@ class App extends BaseConfig
|
||||
*
|
||||
* http://example.com/
|
||||
*/
|
||||
// public string $baseURL = 'http://localhost:8080/';
|
||||
public string $baseURL = 'https://vibhav.vijayabharathambooks.com/';
|
||||
public string $baseURL = 'http://localhost/vb_book/';
|
||||
|
||||
/**
|
||||
* Allowed Hostnames in the Site URL other than the hostname in the baseURL.
|
||||
|
||||
@ -202,6 +202,16 @@ $routes->get('/payment_process','Payment::payment_process');
|
||||
$routes->get('payment_success','Payment::payment_success');
|
||||
$routes->match(['get','post'],'/subscription_renewal/(:any)','Payment::index/$1');
|
||||
$routes->match(['get','post'],'payment_status','Payment::paymentStatus');
|
||||
$routes->post('payment_reconcile','Payment::reconcileOrder');
|
||||
|
||||
|
||||
// Logs -> List/View/Download
|
||||
|
||||
$routes->group('logs', ['namespace' => 'App\Controllers'], function ($routes) {
|
||||
$routes->get('/', 'LogViewer::index');
|
||||
$routes->get('view/(:any)', 'LogViewer::view/$1');
|
||||
$routes->get('download/(:any)', 'LogViewer::download/$1');
|
||||
});
|
||||
|
||||
|
||||
// Logs
|
||||
|
||||
@ -865,6 +865,9 @@ class ApiIntegration extends ResourceController
|
||||
$basic_message .= $insert_result['info'] ? " Invoice id : " . $insert_result['info'] : "Invoice details Not Inserted";
|
||||
$insert_result['info'] ? $this->logger->info("Api SaveSalesDetails : Invoice id = ".$insert_result['info']):"";
|
||||
$insert_result['err'] ? $this->logger->error("Api SaveSalesDetails : Err = ".$insert_result['err']):"";
|
||||
if ($insert_result['info']) {
|
||||
log_message('info', '[PAYMENT] Online store payment received — WooCommerce order ' . $wordpress_order_id . ', invoice ' . ($invoice_data['invoice_number'] ?? '') . ', amount Rs.' . ($invoice_data['exact_total_amount'] ?? $invoice_data['total_amount'] ?? 0) . ', method ' . ($invoice_data['payment_method'] ?? '') . ', payment status ' . ($invoice_data['payment_status'] ?? ''));
|
||||
}
|
||||
} else {
|
||||
$last_insert_invoice_id = $invoice_id;
|
||||
$customer_where = ['invoice_id' => $invoice_id, 'isactive' => 1, 'wp_api_order_id' => $wordpress_order_id];
|
||||
@ -875,6 +878,9 @@ class ApiIntegration extends ResourceController
|
||||
$basic_message .= "Invoice id : " . $last_insert_invoice_id;
|
||||
$update_result['info'] ? $this->logger->info("Api SaveSalesDetails : Invoice id : " . $last_insert_invoice_id . " ( " . $update_result['info'] . ")"):"";
|
||||
$update_result['err'] ? $this->logger->error("Api SaveSalesDetails : Err = ".$update_result['err']):"";
|
||||
if ($update_result['info']) {
|
||||
log_message('info', '[PAYMENT] Online store payment updated — WooCommerce order ' . $wordpress_order_id . ', invoice ' . ($invoice_data['invoice_number'] ?? '') . ', amount Rs.' . ($invoice_data['exact_total_amount'] ?? $invoice_data['total_amount'] ?? 0) . ', method ' . ($invoice_data['payment_method'] ?? '') . ', payment status ' . ($invoice_data['payment_status'] ?? ''));
|
||||
}
|
||||
}
|
||||
|
||||
$line_item_data = [];
|
||||
|
||||
@ -424,6 +424,7 @@ class Invoice extends BaseController
|
||||
// Send notification if invoice is approved
|
||||
$this->logger->info($msg_flag_name . ": ID = " . $invoice_id . ", Status =" . $invoice_status);
|
||||
if ($invoice_status == 'Approved' && $invoice_id != "") {
|
||||
log_message('info', '[PAYMENT] Approved ' . trim($msg_flag_name) . ' saved with payment — invoice ID ' . $invoice_id);
|
||||
|
||||
if(null!=($this->request->getPost('contact_method_mail'))){
|
||||
$contact_method['msg_mail'] = 1;
|
||||
@ -444,6 +445,7 @@ class Invoice extends BaseController
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("Error Occurred: " . $e->getMessage());
|
||||
log_message('error', '[PAYMENT] Invoice save failed: ' . $e->getMessage());
|
||||
session()->setFlashdata('error', 'Message: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
@ -460,6 +462,7 @@ public function create_or_update_invoice($invoice_id, $msg_flag_name)
|
||||
$data['created_by'] = (int)get_logged_user_id();
|
||||
if ($model->insert($data, 'invoices')) {
|
||||
$invoice_id = $model->insertID();
|
||||
$this->logInvoicePayment('created', $data, (int) $invoice_id);
|
||||
if($data['status'] == 'Approved'){
|
||||
session()->setFlashdata('success', $msg_flag_name . 'has been added successfully.');
|
||||
$this->logger->info($msg_flag_name . ": Added successfully. ID = " . $invoice_id);
|
||||
@ -474,6 +477,7 @@ public function create_or_update_invoice($invoice_id, $msg_flag_name)
|
||||
} else {
|
||||
$data['updated_by'] = (int)get_logged_user_id();
|
||||
if ($model->update($invoice_id, $data)) {
|
||||
$this->logInvoicePayment('updated', $data, (int) $invoice_id);
|
||||
session()->setFlashdata('success', $msg_flag_name . 'has been updated successfully.');
|
||||
$this->logger->info($msg_flag_name . ": Updated successfully. ID = " . $invoice_id);
|
||||
} else {
|
||||
@ -554,7 +558,6 @@ public function create_or_update_subscription($invoice_id,$invoice_status, $msg_
|
||||
$renewal = 0;
|
||||
if (!empty($membership_id)){
|
||||
$sub_id = $subModel->select('sub_id')->where('membership_id',$membership_id)->first();
|
||||
log_message('error','going to call the function');
|
||||
$this->checkPaymentStatus($membership_id);
|
||||
}
|
||||
foreach ($invoiceItems as $item) {
|
||||
@ -606,22 +609,38 @@ public function create_or_update_subscription($invoice_id,$invoice_status, $msg_
|
||||
}
|
||||
|
||||
public function checkPaymentStatus($membership_id){
|
||||
log_message("error","Function Called");
|
||||
try {
|
||||
$id = $this->paymentModel->where('membership_id', $membership_id)->where('payment_status','Not Received')->first()['id'];
|
||||
if ($id) {
|
||||
$data['status'] = 999999;
|
||||
$data['payment_status'] = "Approved";
|
||||
$data['updated_by'] = (int)get_logged_user_id();
|
||||
$this->paymentModel->update($id, $data);
|
||||
log_message('error', 'Payment Status Found and updated by User' . $data['updated_by']);
|
||||
$paymentRow = $this->paymentModel->where('membership_id', $membership_id)->where('payment_status','Not Received')->first();
|
||||
if ($paymentRow) {
|
||||
$this->paymentModel->update($paymentRow['id'], [
|
||||
'status' => 999999,
|
||||
'payment_status' => 'Approved',
|
||||
'updated_by' => (int) get_logged_user_id(),
|
||||
]);
|
||||
log_message('info', '[PAYMENT] Staff recorded offline renewal for membership ' . $membership_id . ' — linked Paytm order ' . ($paymentRow['order_id'] ?? '') . ' marked as Approved by user ' . get_logged_user_id());
|
||||
} else {
|
||||
log_message("error", "id not found" . $membership_id);
|
||||
log_message('debug', '[PAYMENT] No pending Paytm payment found to approve for membership ' . $membership_id);
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
log_message('error','Id not found on the checkpaymentstatus ');
|
||||
} catch (\Exception $e) {
|
||||
log_message('warning', '[PAYMENT] Could not update payment status for membership ' . $membership_id . ': ' . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function logInvoicePayment(string $action, array $invoiceData, int $invoiceId): void
|
||||
{
|
||||
$type = ((int) ($invoiceData['invoice_type'] ?? 0) === 2) ? 'Subscription' : 'Invoice';
|
||||
$status = $invoiceData['status'] ?? 'Unknown';
|
||||
$method = $invoiceData['payment_method'] ?? 'Not specified';
|
||||
$amount = $invoiceData['exact_total_amount'] ?? ($invoiceData['total_amount'] ?? 0);
|
||||
$number = $invoiceData['invoice_number'] ?? (string) $invoiceId;
|
||||
$customerId = $invoiceData['customer_id'] ?? '';
|
||||
|
||||
if ($status === 'Draft') {
|
||||
log_message('info', '[PAYMENT] ' . $type . ' draft saved — invoice ' . $number . ', customer ' . $customerId . ', amount Rs.' . $amount . '. Payment not recorded yet.');
|
||||
return;
|
||||
}
|
||||
|
||||
log_message('info', '[PAYMENT] ' . $type . ' ' . $action . ' — invoice ' . $number . ', customer ' . $customerId . ', amount Rs.' . $amount . ', method ' . $method . ', payment status ' . ($invoiceData['payment_status'] ?? ''));
|
||||
}
|
||||
|
||||
|
||||
@ -740,12 +759,17 @@ public function create_or_update_subscription($invoice_id,$invoice_status, $msg_
|
||||
$this->logger->Info("Invoice : Going to Inactive ID = " . $id);
|
||||
|
||||
if ($existed) {
|
||||
$invoiceRow = $model->select('invoice_number, payment_method, payment_status, total_amount')
|
||||
->where('invoice_id', (int) $id)->first();
|
||||
$data['isactive'] = 0;
|
||||
$data['updated_by'] = get_logged_user_id();
|
||||
|
||||
if ($model->update($id, $data)) {
|
||||
session()->setFlashdata('success', 'Deleted successfully.');
|
||||
$this->logger->info("Invoice: has been Inactived successfully. Inactived ID = " . $id);
|
||||
if ($invoiceRow && ($invoiceRow['payment_status'] ?? '') === 'Paid') {
|
||||
log_message('warning', '[PAYMENT] Paid invoice ' . ($invoiceRow['invoice_number'] ?? '') . ' was deleted (ID ' . $id . '), method ' . ($invoiceRow['payment_method'] ?? ''));
|
||||
}
|
||||
} else {
|
||||
$this->logger->error("Invoice: Not able to Inactive ID =" . $id);
|
||||
throw new \Exception("Data Not able to Deleted");
|
||||
@ -779,8 +803,13 @@ public function create_or_update_subscription($invoice_id,$invoice_status, $msg_
|
||||
$where = ['isactive' => 1, 'status' => 'Approved', 'invoice_id' => (int)$id];
|
||||
$details = $model->where($where)->findAll();
|
||||
if (empty($details)) { // Array Empty Means allow to Approve.
|
||||
$invoiceRow = $model->select('invoice_number, customer_id, total_amount, exact_total_amount, payment_method, payment_status, invoice_type')
|
||||
->where('invoice_id', (int) $id)->first();
|
||||
$data = ['status' => 'Approved', 'updated_by' => get_logged_user_id()];
|
||||
if ($model->update($id, $data)) {
|
||||
if ($invoiceRow) {
|
||||
$this->logInvoicePayment('approved', array_merge($invoiceRow, ['status' => 'Approved']), (int) $id);
|
||||
}
|
||||
$this->approve_notifications((int)$id);
|
||||
session()->setFlashdata('success', 'Invoice has been Approved Successfully.');
|
||||
$this->logger->info("Invoice: has been Approved successfully. ID = " . $id);
|
||||
|
||||
167
app/Controllers/LogViewer.php
Normal file
167
app/Controllers/LogViewer.php
Normal file
@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
class LogViewer extends BaseController
|
||||
{
|
||||
protected $logsPath;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->logsPath = WRITEPATH . 'logs/';
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$files = [];
|
||||
|
||||
if (is_dir($this->logsPath)) {
|
||||
$items = scandir($this->logsPath);
|
||||
|
||||
foreach ($items as $item) {
|
||||
if ($item === '.' || $item === '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fullPath = $this->logsPath . $item;
|
||||
|
||||
if (is_file($fullPath)) {
|
||||
$files[] = [
|
||||
'name' => $item,
|
||||
'size' => $this->formatSize(filesize($fullPath)),
|
||||
'modified' => date('Y-m-d H:i:s', filemtime($fullPath)),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usort($files, function ($a, $b) {
|
||||
return strcmp($b['modified'], $a['modified']);
|
||||
});
|
||||
|
||||
$showPayment = $this->request->getGet('payment') === '1';
|
||||
$entries = [];
|
||||
$lineCount = 0;
|
||||
|
||||
if ($showPayment) {
|
||||
foreach ($files as $file) {
|
||||
$fullPath = $this->logsPath . $file['name'];
|
||||
$lines = $this->extractPaymentLogLines($fullPath);
|
||||
|
||||
if (!empty($lines)) {
|
||||
$entries[] = [
|
||||
'file' => $file['name'],
|
||||
'lines' => $lines,
|
||||
];
|
||||
$lineCount += count($lines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data['files'] = $files;
|
||||
$data['showPayment'] = $showPayment;
|
||||
$data['entries'] = $entries;
|
||||
$data['lineCount'] = $lineCount;
|
||||
$data['page_name'] = $showPayment ? 'Payment Logs' : 'Log Files';
|
||||
|
||||
$this->render_page('logviewer/index', $data);
|
||||
}
|
||||
|
||||
public function view($filename = null)
|
||||
{
|
||||
$filename = $this->sanitizeFilename($filename);
|
||||
|
||||
if (!$filename) {
|
||||
return redirect()->to('/logs')->with('error', 'Invalid file name.');
|
||||
}
|
||||
|
||||
$fullPath = $this->logsPath . $filename;
|
||||
|
||||
if (!is_file($fullPath)) {
|
||||
return redirect()->to('/logs')->with('error', 'File not found.');
|
||||
}
|
||||
|
||||
$showPayment = $this->request->getGet('payment') === '1';
|
||||
$content = file_get_contents($fullPath);
|
||||
|
||||
if ($showPayment) {
|
||||
$lines = $this->extractPaymentLogLines($fullPath);
|
||||
$content = !empty($lines) ? implode("\n", $lines) : '';
|
||||
}
|
||||
|
||||
$data['filename'] = $filename;
|
||||
$data['content'] = $content;
|
||||
$data['showPayment'] = $showPayment;
|
||||
$data['page_name'] = $showPayment ? 'Payment Logs' : 'View Log';
|
||||
|
||||
$this->render_page('logviewer/view', $data);
|
||||
}
|
||||
|
||||
public function download($filename = null)
|
||||
{
|
||||
$filename = $this->sanitizeFilename($filename);
|
||||
|
||||
if (!$filename) {
|
||||
return redirect()->to('/logs')->with('error', 'Invalid file name.');
|
||||
}
|
||||
|
||||
$fullPath = $this->logsPath . $filename;
|
||||
|
||||
if (!is_file($fullPath)) {
|
||||
return redirect()->to('/logs')->with('error', 'File not found.');
|
||||
}
|
||||
|
||||
return $this->response->download($fullPath, null);
|
||||
}
|
||||
|
||||
private function extractPaymentLogLines(string $fullPath): array
|
||||
{
|
||||
if (!is_readable($fullPath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$lines = [];
|
||||
$handle = fopen($fullPath, 'r');
|
||||
|
||||
if ($handle === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
while (($line = fgets($handle)) !== false) {
|
||||
if (strpos($line, '[PAYMENT]') !== false) {
|
||||
$lines[] = rtrim($line, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
private function sanitizeFilename($filename)
|
||||
{
|
||||
if (!$filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$filename = basename($filename);
|
||||
|
||||
if (!preg_match('/^[A-Za-z0-9_\-\.]+\.(log|php|txt|html)$/', $filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
private function formatSize($bytes)
|
||||
{
|
||||
if ($bytes >= 1073741824) {
|
||||
return number_format($bytes / 1073741824, 2) . ' GB';
|
||||
} elseif ($bytes >= 1048576) {
|
||||
return number_format($bytes / 1048576, 2) . ' MB';
|
||||
} elseif ($bytes >= 1024) {
|
||||
return number_format($bytes / 1024, 2) . ' KB';
|
||||
}
|
||||
return $bytes . ' bytes';
|
||||
}
|
||||
}
|
||||
@ -58,8 +58,7 @@ class Payment extends BaseController
|
||||
];
|
||||
$response['favicon'] = !empty($details[0]['favicon']) && file_exists(FCPATH."public/uploads/".$details[0]['favicon']) ? base_url("public/uploads/".$details[0]['favicon']) : base_url("public/uploads/default.ico");
|
||||
|
||||
// var_dump($response);die();
|
||||
log_message('error','Membership ID : '.$membership_id.' renewal link clicked and user is redirected to subscription renewal Page');
|
||||
log_message('info', '[PAYMENT] Customer opened renewal page for membership ' . $membership_id . ', amount Rs.' . $amount);
|
||||
return view('subscription_renewal',$response);
|
||||
}
|
||||
else{
|
||||
@ -87,7 +86,7 @@ class Payment extends BaseController
|
||||
|
||||
}
|
||||
|
||||
log_message('error','Renewal link clicked and user is redirected to subscription renewal Page');
|
||||
log_message('info', '[PAYMENT] Customer opened renewal page for membership ' . ($membership_id ?? ''));
|
||||
return view('subscription_renewal',$response);
|
||||
}
|
||||
else {
|
||||
@ -96,7 +95,7 @@ class Payment extends BaseController
|
||||
$scheme = $model2->get_subscription_details_by_membership_id($membership_id);
|
||||
$customer_id = $model2->select('customer_id')->where('membership_id',$membership_id)->first();
|
||||
$customer_details = $model->get_customer_details_by_customer_id($customer_id);
|
||||
log_message('info','inside the method post');
|
||||
log_message('debug', '[PAYMENT] Renewal page loaded customer details for membership ' . $membership_id);
|
||||
$book_id = env('RENEWAL_SCHEME_ID');
|
||||
$price = $bookModel->select('price')->where('book_id', $book_id)->first();
|
||||
$amount = $price['price'];
|
||||
@ -148,56 +147,51 @@ class Payment extends BaseController
|
||||
'payment_status'=> 'Not Received'
|
||||
];
|
||||
$result = $this->paymentModel->insert($payment_status_data);
|
||||
if ($result){
|
||||
log_message('info','Data Inserted to Payment Status '.json_encode($payment_status_data));
|
||||
if ($result) {
|
||||
log_message('info', '[PAYMENT] Payment initiated — customer ' . $CUST_ID . ', membership ' . $membership_id . ', order ' . $ORDER_ID . ', amount Rs.' . $TXN_AMOUNT . ' via ' . ($payment_method === 'mobile' ? 'Mobile' : 'Web'));
|
||||
}
|
||||
log_message('error','Data Sent to Paytm: '.json_encode($data['paramList']));
|
||||
log_message('info', '[PAYMENT] Redirecting customer to Paytm gateway for order ' . $ORDER_ID);
|
||||
return view('/tresponse', $data);
|
||||
}
|
||||
|
||||
public function tresponse() {
|
||||
$paytmChecksum = "";
|
||||
$paramList = $_POST;
|
||||
//print_r($paramList);
|
||||
$isValidChecksum = "FALSE";
|
||||
$paramList = $_POST;
|
||||
// dd($paramList);
|
||||
log_message('error','data receieved through Paytm: '.json_encode($paramList));
|
||||
$paytmChecksum = isset($_POST["CHECKSUMHASH"]) ? $_POST["CHECKSUMHASH"] : "";
|
||||
$result['receivedFromPaytm'] = $paramList;
|
||||
// Verify checksum
|
||||
$paramList = $_POST;
|
||||
$orderId = $paramList['ORDERID'] ?? 'unknown';
|
||||
$paytmChecksum = $paramList['CHECKSUMHASH'] ?? '';
|
||||
$txnStatus = $paramList['STATUS'] ?? 'unknown';
|
||||
|
||||
log_message('info', '[PAYMENT] Paytm callback received for order ' . $orderId . ' with status ' . $txnStatus);
|
||||
|
||||
$isValidChecksum = verifychecksum_e($paramList, env('Merchant_Key'), $paytmChecksum);
|
||||
|
||||
if ($isValidChecksum == "TRUE") {
|
||||
//echo "<b>Checksum matched.</b><br/>";
|
||||
|
||||
if (isset($_POST) && count($_POST) > 0) {
|
||||
// foreach($_POST as $paramName => $paramValue) {
|
||||
// // echo "<br/>" . htmlspecialchars($paramName) . " = " . htmlspecialchars($paramValue);
|
||||
// }
|
||||
log_message('error',json_encode($paramList));
|
||||
log_message('error','data receieved through Paytm under the if condition post> 0: '.json_encode($paramList));
|
||||
|
||||
}
|
||||
if ($_POST["STATUS"] == "TXN_SUCCESS") {
|
||||
$queryString = http_build_query($paramList);
|
||||
echo "<b>Transaction status is success</b><br/>";
|
||||
log_message('error','Transaction is Successfull');
|
||||
return redirect()->to(base_url('/payment_process?' . $queryString));
|
||||
} else {
|
||||
echo "<b>Processing ...</b><br/>";
|
||||
$queryString = http_build_query($paramList);
|
||||
log_message('error','Transaction is Failed');
|
||||
|
||||
return redirect()->to(base_url('/payment_failure?' . $queryString));
|
||||
}
|
||||
} else {
|
||||
log_message('error','Checksum Mismatched');
|
||||
if ($isValidChecksum !== 'TRUE') {
|
||||
log_message('error', '[PAYMENT] Paytm callback rejected — checksum mismatch for order ' . $orderId . '. Payment was not recorded.');
|
||||
return view('/payment_failure');
|
||||
}
|
||||
|
||||
|
||||
log_message('info', '[PAYMENT] Paytm callback verified successfully for order ' . $orderId);
|
||||
|
||||
if ($txnStatus === 'TXN_SUCCESS') {
|
||||
$processResult = $this->processSuccessfulPayment($paramList);
|
||||
|
||||
if ($processResult['success'] || $processResult['already_processed']) {
|
||||
log_message('info', '[PAYMENT] Renewal payment recorded successfully for order ' . $orderId);
|
||||
return redirect()->to(base_url('/payment_success'));
|
||||
}
|
||||
|
||||
log_message('error', '[PAYMENT] Paytm reported success but renewal could not be saved for order ' . $orderId . ': ' . $processResult['message'] . '. Customer will be sent to retry page.');
|
||||
|
||||
$queryString = http_build_query($paramList);
|
||||
return redirect()->to(base_url('/payment_process?' . $queryString));
|
||||
}
|
||||
|
||||
$this->updateFailedPayment($paramList);
|
||||
log_message('warning', '[PAYMENT] Paytm payment failed or was cancelled for order ' . $orderId . ' — status: ' . $txnStatus);
|
||||
|
||||
$queryString = http_build_query($paramList);
|
||||
return redirect()->to(base_url('/payment_failure?' . $queryString));
|
||||
}
|
||||
public function payment_failure(){
|
||||
public function payment_failure(){
|
||||
$paramList = [
|
||||
'BANKTXNID' => $this->request->getVar('BANKTXNID'),
|
||||
'CHECKSUMHASH' => $this->request->getVar('CHECKSUMHASH'),
|
||||
@ -208,194 +202,361 @@ public function payment_failure(){
|
||||
'TXNAMOUNT' => $this->request->getVar('TXNAMOUNT'),
|
||||
'TXNDATE' => $this->request->getVar('TXNDATE'),
|
||||
'TXNID' => $this->request->getVar('TXNID'),
|
||||
'is_active' => 1
|
||||
'is_active' => 1,
|
||||
];
|
||||
|
||||
$model4 = new TransactionModel();
|
||||
$model4->insert($paramList);
|
||||
// $insertId = $model4->insertID();
|
||||
$payment_status_id = $this->paymentModel->select('id')->where('order_id',$this->request->getVar('ORDERID'))->first()['id'];
|
||||
// echo "payment status id :";
|
||||
// var_dump($payment_status_id);die();
|
||||
// $payement_status_update['status'] = $insertId;
|
||||
$converted_status = ucfirst(strtolower(str_replace("TXN_", "", $this->request->getVar('STATUS'))));
|
||||
$payement_status_update['payment_status'] = $converted_status;
|
||||
$orderId = $paramList['ORDERID'] ?? '';
|
||||
if (! empty($orderId)) {
|
||||
log_message('info', '[PAYMENT] Customer reached payment failure page for order ' . $orderId . ', status ' . ($paramList['STATUS'] ?? 'unknown'));
|
||||
}
|
||||
|
||||
// $payement_status_update['status'] = $payment_status_id;
|
||||
$this->updateFailedPayment($paramList);
|
||||
|
||||
$updated = $this->paymentModel->update($payment_status_id, $payement_status_update);
|
||||
log_message('error', 'Payment Status Updated: ' . json_encode($updated));
|
||||
|
||||
return view('/payment_failure');
|
||||
}
|
||||
|
||||
public function payment_process() {
|
||||
echo "Do not hit refresh or go back. Confirming your Order";
|
||||
helper('session');
|
||||
helper('financial_year_helper');
|
||||
$subModel = new SubscriptionModel();
|
||||
$ORDER_ID = $this->request->getVar('ORDERID');
|
||||
$parts = explode('_', $ORDER_ID);
|
||||
$customer_id = (int)$parts[0];
|
||||
$paramList = $this->request->getGet();
|
||||
$orderId = $paramList['ORDERID'] ?? 'unknown';
|
||||
|
||||
log_message('info', '[PAYMENT] Processing renewal page opened for order ' . $orderId . ' (browser follow-up after Paytm)');
|
||||
|
||||
$processResult = $this->processSuccessfulPayment($paramList);
|
||||
|
||||
if ($processResult['success'] || $processResult['already_processed']) {
|
||||
return redirect()->to(base_url('/payment_success'));
|
||||
}
|
||||
|
||||
log_message('error', '[PAYMENT] Could not complete renewal for order ' . $orderId . ': ' . $processResult['message']);
|
||||
|
||||
return redirect()->to(base_url('/payment_failure?' . http_build_query($paramList)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Record a failed Paytm payment and update payment status.
|
||||
*/
|
||||
private function updateFailedPayment(array $paramList): void
|
||||
{
|
||||
$orderId = $paramList['ORDERID'] ?? null;
|
||||
if (empty($orderId)) {
|
||||
log_message('warning', '[PAYMENT] Failed payment callback received without an order ID');
|
||||
return;
|
||||
}
|
||||
|
||||
$model4 = new TransactionModel();
|
||||
$model4->insert([
|
||||
'BANKTXNID' => $paramList['BANKTXNID'] ?? null,
|
||||
'CHECKSUMHASH' => $paramList['CHECKSUMHASH'] ?? null,
|
||||
'GATEWAYNAME' => $paramList['GATEWAYNAME'] ?? null,
|
||||
'ORDERID' => $orderId,
|
||||
'PAYMENTMODE' => $paramList['PAYMENTMODE'] ?? null,
|
||||
'STATUS' => $paramList['STATUS'] ?? null,
|
||||
'TXNAMOUNT' => $paramList['TXNAMOUNT'] ?? null,
|
||||
'TXNDATE' => $paramList['TXNDATE'] ?? null,
|
||||
'TXNID' => $paramList['TXNID'] ?? null,
|
||||
'isactive' => 1,
|
||||
]);
|
||||
|
||||
$paymentRow = $this->paymentModel->select('id')->where('order_id', $orderId)->first();
|
||||
if ($paymentRow === null) {
|
||||
log_message('warning', '[PAYMENT] No payment record found to mark as failed for order ' . $orderId);
|
||||
return;
|
||||
}
|
||||
|
||||
$status = $paramList['STATUS'] ?? '';
|
||||
$convertedStatus = ucfirst(strtolower(str_replace('TXN_', '', $status)));
|
||||
$this->paymentModel->update($paymentRow['id'], [
|
||||
'payment_status' => $convertedStatus,
|
||||
]);
|
||||
|
||||
log_message('info', '[PAYMENT] Payment marked as ' . $convertedStatus . ' for order ' . $orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create invoice, subscription, and transaction for a successful Paytm payment.
|
||||
*
|
||||
* @return array{success: bool, already_processed: bool, message: string}
|
||||
*/
|
||||
private function processSuccessfulPayment(array $paramList): array
|
||||
{
|
||||
helper(['session', 'financial_year_helper']);
|
||||
|
||||
$orderId = $paramList['ORDERID'] ?? null;
|
||||
if (empty($orderId)) {
|
||||
return ['success' => false, 'already_processed' => false, 'message' => 'Missing order ID'];
|
||||
}
|
||||
|
||||
if ($this->isOrderAlreadyProcessed($orderId)) {
|
||||
log_message('info', '[PAYMENT] Order ' . $orderId . ' was already processed — skipping duplicate renewal');
|
||||
return ['success' => true, 'already_processed' => true, 'message' => 'Already processed'];
|
||||
}
|
||||
|
||||
$parts = explode('_', $orderId, 3);
|
||||
if (count($parts) < 2) {
|
||||
log_message('error', '[PAYMENT] Invalid order ID format for order ' . $orderId);
|
||||
return ['success' => false, 'already_processed' => false, 'message' => 'Invalid order ID format'];
|
||||
}
|
||||
|
||||
$customer_id = (int) $parts[0];
|
||||
$past_membership_id = $parts[1];
|
||||
// $payment_method = $this->request->getVar('PAYMENTMODE');
|
||||
$payment_method = 'paytm';
|
||||
//dd($past_membership_id);
|
||||
// $parts = explode('_', $ORDER_ID);
|
||||
// $customer_id = (int)$parts[0];
|
||||
$currentDate = date('Y-m-d');
|
||||
$payment_method = 'paytm';
|
||||
$currentDate = date('Y-m-d');
|
||||
|
||||
$db = \Config\Database::connect();
|
||||
$subModel = new SubscriptionModel();
|
||||
$bookModel = new BooksModel();
|
||||
$model = new InvoiceModel();
|
||||
$db = \Config\Database::connect();
|
||||
$baddress = $db->table('customer_addresses')->select('address_1,customer_address_id')->where('customer_id',$customer_id)->where('address_type',1)->get()->getRowArray();
|
||||
$saddress = $db->table('customer_addresses')->select('address_1,customer_address_id')->where('customer_id',$customer_id)->where('address_type',2)->get()->getRowArray();
|
||||
$next_id_row = $db->table('invoice_number_formatting')->select('next_id, left_pad')->get()->getRowArray();
|
||||
|
||||
$filtered_data = [
|
||||
[
|
||||
'next_id' => $next_id_row['next_id'],
|
||||
'left_pad' => $next_id_row['left_pad']
|
||||
]
|
||||
];
|
||||
$financial_year = get_financial_year();
|
||||
|
||||
$result = $this->generateSerialNumber($filtered_data, $financial_year);
|
||||
//var_dump($result);die();
|
||||
$model = new InvoiceModel();
|
||||
|
||||
try {
|
||||
$db->transStart();
|
||||
|
||||
$baddress = $db->table('customer_addresses')
|
||||
->select('address_1,customer_address_id')
|
||||
->where('customer_id', $customer_id)
|
||||
->where('address_type', 1)
|
||||
->get()->getRowArray();
|
||||
|
||||
$saddress = $db->table('customer_addresses')
|
||||
->select('address_1,customer_address_id')
|
||||
->where('customer_id', $customer_id)
|
||||
->where('address_type', 2)
|
||||
->get()->getRowArray();
|
||||
|
||||
$next_id_row = $db->table('invoice_number_formatting')
|
||||
->select('next_id, left_pad')
|
||||
->get()->getRowArray();
|
||||
|
||||
if ($next_id_row === null) {
|
||||
throw new \RuntimeException('Invoice numbering configuration not found');
|
||||
}
|
||||
|
||||
$filtered_data = [['next_id' => $next_id_row['next_id'], 'left_pad' => $next_id_row['left_pad']]];
|
||||
$financial_year = get_financial_year();
|
||||
$result = $this->generateSerialNumber($filtered_data, $financial_year);
|
||||
$invoice_number = $result['serial_number'];
|
||||
$next_id_numeric = $result['next_id'];
|
||||
$book_id = env('RENEWAL_SCHEME_ID');
|
||||
$price = $bookModel->select('price')->where('book_id', $book_id)->first();
|
||||
$amount = $price['price'];
|
||||
$data = [
|
||||
'invoice_number' => $invoice_number,
|
||||
'invoice_type' => 2,
|
||||
'customer_id' => $customer_id,
|
||||
'payment_status' => 'Paid',
|
||||
'status'=>'Approved',
|
||||
'subtotal' => $amount,
|
||||
'sub_total' => $amount,
|
||||
'exact_total_amount' => $amount,
|
||||
'grand_total' => $amount,
|
||||
'total_amount' => $amount,
|
||||
'invoice_date' => $currentDate,
|
||||
'shipping_address'=> $saddress['address_1'],
|
||||
'shipping_address_id' => isset($saddress['customer_address_id']) ? $saddress['customer_address_id'] : '',
|
||||
'billing_address'=> $baddress['address_1'],
|
||||
'billing_address_id' => isset($baddress['customer_address_id']) ? $baddress['customer_address_id'] : '',
|
||||
'payment_method' => $payment_method,
|
||||
'business_id' =>2
|
||||
];
|
||||
$model->save($data);
|
||||
log_message('error','invoice details added to invoice table');
|
||||
$update_invoice_numbering = [
|
||||
'id' => 1,
|
||||
'id_formating' => get_financial_year(),
|
||||
'next_id' => (int)$next_id_numeric,
|
||||
'business_id' => 2,
|
||||
'updated_by' => null !== ($userId = get_logged_user_id()) ? $userId : '',
|
||||
];
|
||||
// var_dump($update_invoice_numbering);die();
|
||||
$save_invoice = new Invoice();
|
||||
$save_invoice->update_number_formatting($update_invoice_numbering);
|
||||
//get the invoice id to insert into the invoiceitems table
|
||||
$invoice_id = $model->select('invoice_id')->where('invoice_number',$invoice_number)->first();
|
||||
$previous_to_sub = $subModel->select('to_subscription')->where('customer_id',$customer_id)->where('membership_id',$past_membership_id)->first();
|
||||
$new_subscription_date = $previous_to_sub['to_subscription'];
|
||||
// Create a DateTime object from the existing subscription date
|
||||
$date = new \DateTime($new_subscription_date);
|
||||
$currentDate = date('Y-m-d');
|
||||
if ($currentDate > $new_subscription_date){
|
||||
$fsubscription = $currentDate; //if subscription is already expired
|
||||
|
||||
}else{
|
||||
// Add one day from previous subscrption's to subscription date
|
||||
$book_id = env('RENEWAL_SCHEME_ID');
|
||||
$price = $bookModel->select('price')->where('book_id', $book_id)->first();
|
||||
$amount = $price['price'] ?? ($paramList['TXNAMOUNT'] ?? 0);
|
||||
|
||||
$data = [
|
||||
'invoice_number' => $invoice_number,
|
||||
'invoice_type' => 2,
|
||||
'customer_id' => $customer_id,
|
||||
'payment_status' => 'Paid',
|
||||
'status' => 'Approved',
|
||||
'subtotal' => $amount,
|
||||
'sub_total' => $amount,
|
||||
'exact_total_amount' => $amount,
|
||||
'grand_total' => $amount,
|
||||
'total_amount' => $amount,
|
||||
'invoice_date' => $currentDate,
|
||||
'shipping_address' => $saddress['address_1'] ?? '',
|
||||
'shipping_address_id' => $saddress['customer_address_id'] ?? '',
|
||||
'billing_address' => $baddress['address_1'] ?? '',
|
||||
'billing_address_id' => $baddress['customer_address_id'] ?? '',
|
||||
'payment_method' => $payment_method,
|
||||
'business_id' => 2,
|
||||
];
|
||||
|
||||
$model->save($data);
|
||||
log_message('info', '[PAYMENT] Invoice ' . $invoice_number . ' created for customer ' . $customer_id . ' after Paytm payment, order ' . $orderId);
|
||||
|
||||
$save_invoice = new Invoice();
|
||||
$save_invoice->update_number_formatting([
|
||||
'id' => 1,
|
||||
'id_formating' => get_financial_year(),
|
||||
'next_id' => (int) $next_id_numeric,
|
||||
'business_id' => 2,
|
||||
'updated_by' => null !== ($userId = get_logged_user_id()) ? $userId : '',
|
||||
]);
|
||||
|
||||
$invoice_id = $model->select('invoice_id')->where('invoice_number', $invoice_number)->first();
|
||||
if ($invoice_id === null) {
|
||||
throw new \RuntimeException('Invoice was not saved');
|
||||
}
|
||||
|
||||
$previous_to_sub = $subModel->select('to_subscription')
|
||||
->where('customer_id', $customer_id)
|
||||
->where('membership_id', $past_membership_id)
|
||||
->first();
|
||||
|
||||
if ($previous_to_sub === null) {
|
||||
throw new \RuntimeException('Previous subscription not found for membership ' . $past_membership_id);
|
||||
}
|
||||
|
||||
$new_subscription_date = $previous_to_sub['to_subscription'];
|
||||
if ($currentDate > $new_subscription_date) {
|
||||
$fsubscription = $currentDate;
|
||||
} else {
|
||||
$fsubscription = date('Y-m-d', strtotime('+1 day', strtotime($new_subscription_date)));
|
||||
}
|
||||
|
||||
$date->add(new \DateInterval('P1D'));
|
||||
|
||||
$tsubscription = date('Y-m-d', strtotime('+1 year', strtotime($fsubscription)));
|
||||
$data['item_details'] = 3;
|
||||
$requestData = [
|
||||
'invoice_id' =>$invoice_id['invoice_id'],
|
||||
'product' => env('RENEWAL_SCHEME_ID'),
|
||||
'quantity' =>1,
|
||||
'unit_price'=>$data['sub_total'],
|
||||
'subtotal' => $data['sub_total'],
|
||||
'created_on'=>$currentDate,
|
||||
'isactive'=>1,
|
||||
'from_subscription' =>$fsubscription,
|
||||
'to_subscription' =>$tsubscription,
|
||||
|
||||
];
|
||||
$db->table('invoiceitems')->insert($requestData);
|
||||
log_message('error','invoice details added to invoice items table');
|
||||
|
||||
$db->table('invoiceitems')->insert([
|
||||
'invoice_id' => $invoice_id['invoice_id'],
|
||||
'product' => env('RENEWAL_SCHEME_ID'),
|
||||
'quantity' => 1,
|
||||
'unit_price' => $data['sub_total'],
|
||||
'subtotal' => $data['sub_total'],
|
||||
'created_on' => $currentDate,
|
||||
'isactive' => 1,
|
||||
'from_subscription' => $fsubscription,
|
||||
'to_subscription' => $tsubscription,
|
||||
]);
|
||||
|
||||
log_message('info', '[PAYMENT] Subscription renewed from ' . $fsubscription . ' to ' . $tsubscription . ' for customer ' . $customer_id . ', order ' . $orderId);
|
||||
|
||||
$invoice = new Invoice();
|
||||
$contact_method['msg_mail'] = 1;
|
||||
$invoice->approve_notifications((int)$invoice_id['invoice_id'],$contact_method);
|
||||
$model3 = new SubscriptionModel();
|
||||
$invoice->approve_notifications((int) $invoice_id['invoice_id'], ['msg_mail' => 1]);
|
||||
|
||||
$invoiceController = new Invoice();
|
||||
$membership_id = $invoiceController->generate_membership_id(6);
|
||||
//$membership_id = $model3->select('membership_id')->where('customer_id',$customer_id)->first();
|
||||
// if ($membership_id<=0){
|
||||
// $membership_id = $invoice->generate_membership_id(6);
|
||||
// }
|
||||
$membership_id = $invoiceController->generate_membership_id(6);
|
||||
|
||||
$subscription = $subModel->select('sub_id')->where('membership_id',$past_membership_id)->first();
|
||||
$subscriptionData = [
|
||||
'scheme_id' => env('RENEWAL_SCHEME_ID'),
|
||||
'customer_id' => $customer_id,
|
||||
'invoice_id' => $invoice_id,
|
||||
'from_subscription'=> $fsubscription,
|
||||
'to_subscription' => $tsubscription,
|
||||
'is_renew' => $subscription['sub_id'],
|
||||
'business_id' => 2,
|
||||
'status' => 1,
|
||||
'membership_id' => $membership_id,
|
||||
'isactive' => 1,
|
||||
'business_id' => 2
|
||||
$subscription = $subModel->select('sub_id')
|
||||
->where('membership_id', $past_membership_id)
|
||||
->first();
|
||||
|
||||
];
|
||||
$db->table('subscription')->insert($subscriptionData);
|
||||
log_message('error','subscription details added to subscription table');
|
||||
|
||||
|
||||
|
||||
$paramList = [
|
||||
'BANKTXNID' => $this->request->getVar('BANKTXNID'),
|
||||
'CHECKSUMHASH' => $this->request->getVar('CHECKSUMHASH'),
|
||||
'GATEWAYNAME' => $this->request->getVar('GATEWAYNAME'),
|
||||
'ORDERID' => $this->request->getVar('ORDERID'),
|
||||
'PAYMENTMODE' => $this->request->getVar('PAYMENTMODE'),
|
||||
'STATUS' => $this->request->getVar('STATUS'),
|
||||
'TXNAMOUNT' => $this->request->getVar('TXNAMOUNT'),
|
||||
'TXNDATE' => $this->request->getVar('TXNDATE'),
|
||||
'TXNID' => $this->request->getVar('TXNID'),
|
||||
'invoice_id' => $invoice_id,
|
||||
'is_active' => 1
|
||||
];
|
||||
$db->table('subscription')->insert([
|
||||
'scheme_id' => env('RENEWAL_SCHEME_ID'),
|
||||
'customer_id' => $customer_id,
|
||||
'invoice_id' => $invoice_id['invoice_id'],
|
||||
'from_subscription' => $fsubscription,
|
||||
'to_subscription' => $tsubscription,
|
||||
'is_renew' => $subscription['sub_id'] ?? 0,
|
||||
'business_id' => 2,
|
||||
'status' => 1,
|
||||
'membership_id' => $membership_id,
|
||||
'isactive' => 1,
|
||||
]);
|
||||
|
||||
$model4 = new TransactionModel();
|
||||
$model4->save($paramList);
|
||||
log_message('error','transaction details added to transaction table');
|
||||
$model4->insert([
|
||||
'BANKTXNID' => $paramList['BANKTXNID'] ?? null,
|
||||
'CHECKSUMHASH' => $paramList['CHECKSUMHASH'] ?? null,
|
||||
'GATEWAYNAME' => $paramList['GATEWAYNAME'] ?? null,
|
||||
'ORDERID' => $orderId,
|
||||
'PAYMENTMODE' => $paramList['PAYMENTMODE'] ?? null,
|
||||
'STATUS' => $paramList['STATUS'] ?? 'TXN_SUCCESS',
|
||||
'TXNAMOUNT' => $paramList['TXNAMOUNT'] ?? null,
|
||||
'TXNDATE' => $paramList['TXNDATE'] ?? null,
|
||||
'TXNID' => $paramList['TXNID'] ?? null,
|
||||
'invoice_id' => $invoice_id['invoice_id'],
|
||||
'isactive' => 1,
|
||||
]);
|
||||
|
||||
$insertId = $model4->insertID();
|
||||
$payment_status_id = $this->paymentModel->select('id')->where('order_id',$this->request->getVar('ORDERID'))->first()['id'];
|
||||
// echo "payment status id :";
|
||||
// var_dump($payment_status_id);die();
|
||||
$payement_status_update['status'] = $insertId;
|
||||
$converted_status = ucfirst(strtolower(str_replace("TXN_", "", $this->request->getVar('STATUS'))));
|
||||
$payement_status_update['payment_status'] = $converted_status;
|
||||
$insertId = $model4->getInsertID();
|
||||
|
||||
// $payement_status_update['status'] = $payment_status_id;
|
||||
$paymentRow = $this->paymentModel->select('id')->where('order_id', $orderId)->first();
|
||||
if ($paymentRow !== null) {
|
||||
$this->paymentModel->update($paymentRow['id'], [
|
||||
'status' => $insertId,
|
||||
'payment_status' => 'Success',
|
||||
]);
|
||||
}
|
||||
|
||||
$updated = $this->paymentModel->update($payment_status_id, $payement_status_update);
|
||||
log_message('error', 'Payment Status Updated: ' . json_encode($updated));
|
||||
$db->transComplete();
|
||||
|
||||
if ($db->transStatus() === false) {
|
||||
throw new \RuntimeException('Database transaction failed while saving renewal');
|
||||
}
|
||||
|
||||
log_message('info', 'saved data' . json_encode($data));
|
||||
log_message('info', '[PAYMENT] Renewal completed — order ' . $orderId . ', invoice ' . $invoice_number . ', new membership ' . $membership_id . ', customer ' . $customer_id);
|
||||
|
||||
return redirect()->to(base_url('/payment_success'));
|
||||
return ['success' => true, 'already_processed' => false, 'message' => 'Renewal completed'];
|
||||
} catch (\Throwable $e) {
|
||||
$db->transRollback();
|
||||
log_message('error', '[PAYMENT] Renewal failed for order ' . $orderId . ': ' . $e->getMessage());
|
||||
return ['success' => false, 'already_processed' => false, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
private function isOrderAlreadyProcessed(string $orderId): bool
|
||||
{
|
||||
$paymentRow = $this->paymentModel->where('order_id', $orderId)->first();
|
||||
if ($paymentRow !== null && ($paymentRow['payment_status'] ?? '') !== 'Not Received') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$db = \Config\Database::connect();
|
||||
return $db->table('transactions')
|
||||
->where('ORDERID', $orderId)
|
||||
->where('STATUS', 'TXN_SUCCESS')
|
||||
->countAllResults() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query Paytm for the live status of an order (used to recover stuck payments).
|
||||
*/
|
||||
private function fetchPaytmTransactionStatus(string $orderId): ?array
|
||||
{
|
||||
$requestParamList = [
|
||||
'MID' => env('Merchant_ID'),
|
||||
'ORDERID' => $orderId,
|
||||
];
|
||||
$requestParamList['CHECKSUMHASH'] = getChecksumFromArray($requestParamList, env('Merchant_Key'));
|
||||
|
||||
$response = callAPI(PAYTM_STATUS_QUERY_URL, $requestParamList);
|
||||
|
||||
log_message('info', '[PAYMENT] Checked Paytm status for order ' . $orderId . ' — result: ' . ($response['STATUS'] ?? 'unknown'));
|
||||
|
||||
return is_array($response) ? $response : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconcile a stuck "Not Received" payment by verifying with Paytm and processing if paid.
|
||||
*/
|
||||
public function reconcileOrder()
|
||||
{
|
||||
if (! $this->request->is('post')) {
|
||||
return $this->response->setJSON(['status' => false, 'message' => 'Invalid request']);
|
||||
}
|
||||
|
||||
$orderId = $this->request->getPost('order_id');
|
||||
if (empty($orderId)) {
|
||||
return $this->response->setJSON(['status' => false, 'message' => 'Order ID is required']);
|
||||
}
|
||||
|
||||
log_message('info', '[PAYMENT] Manual reconciliation started for order ' . $orderId);
|
||||
|
||||
if ($this->isOrderAlreadyProcessed($orderId)) {
|
||||
return $this->response->setJSON([
|
||||
'status' => true,
|
||||
'message' => 'This payment was already recorded in the system.',
|
||||
]);
|
||||
}
|
||||
|
||||
$paytmResponse = $this->fetchPaytmTransactionStatus($orderId);
|
||||
if ($paytmResponse === null) {
|
||||
return $this->response->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Could not reach Paytm to verify this payment. Please try again.',
|
||||
]);
|
||||
}
|
||||
|
||||
if (($paytmResponse['STATUS'] ?? '') !== 'TXN_SUCCESS') {
|
||||
log_message('warning', '[PAYMENT] Paytm reports order ' . $orderId . ' is not successful — status: ' . ($paytmResponse['STATUS'] ?? 'unknown'));
|
||||
return $this->response->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Paytm shows this payment as: ' . ($paytmResponse['STATUS'] ?? 'pending/failed') . '. It cannot be recorded as paid.',
|
||||
]);
|
||||
}
|
||||
|
||||
$processResult = $this->processSuccessfulPayment($paytmResponse);
|
||||
if ($processResult['success'] || $processResult['already_processed']) {
|
||||
log_message('info', '[PAYMENT] Manual reconciliation succeeded for order ' . $orderId);
|
||||
return $this->response->setJSON([
|
||||
'status' => true,
|
||||
'message' => 'Payment verified with Paytm and renewal has been recorded successfully.',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Paytm confirmed payment but renewal could not be saved: ' . $processResult['message'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function generateSerialNumber($filtered_data, $financial_year) {
|
||||
@ -410,6 +571,12 @@ public function generateSerialNumber($filtered_data, $financial_year) {
|
||||
return ['serial_number' => $serial_number, 'next_id' => $next_id_numeric];
|
||||
}
|
||||
public function payment_success(){
|
||||
$orderId = $this->request->getGet('ORDERID');
|
||||
if (! empty($orderId)) {
|
||||
log_message('info', '[PAYMENT] Customer reached payment success page for order ' . $orderId);
|
||||
} else {
|
||||
log_message('info', '[PAYMENT] Customer reached payment success page');
|
||||
}
|
||||
return view('payment_success');
|
||||
}
|
||||
|
||||
@ -485,7 +652,6 @@ public function paymentStatus(){
|
||||
return $this->render_page('payment_status_view',$data);
|
||||
}else{
|
||||
$received_data = $this->request->getPost();
|
||||
log_message('error','data received from post '.json_encode($received_data));
|
||||
$dateParts = explode(' - ', $received_data['dateRange']);
|
||||
$status = $received_data['status'];
|
||||
|
||||
@ -496,8 +662,9 @@ public function paymentStatus(){
|
||||
$fromDate = \DateTime::createFromFormat('d/m/Y', $dateParts[0])->format('Y-m-d');
|
||||
$toDate = \DateTime::createFromFormat('d/m/Y', $dateParts[1])->format('Y-m-d');
|
||||
|
||||
log_message('info', '[PAYMENT] Staff viewed payment status report from ' . $fromDate . ' to ' . $toDate . ', showing ' . (((int) $status === 1) ? 'received' : 'not received') . ' payments');
|
||||
|
||||
$payment_data['payment_status_data'] = $this->paymentModel->getPaymentData($fromDate, $toDate,$status);
|
||||
log_message('debug',json_encode($payment_data));
|
||||
|
||||
$html = view('payment_status_table',$payment_data);
|
||||
$data['selected_data'] = $received_data['dateRange'];
|
||||
|
||||
131
app/Views/logviewer/index.php
Normal file
131
app/Views/logviewer/index.php
Normal file
@ -0,0 +1,131 @@
|
||||
<!-- start page title -->
|
||||
<div class="row d-flex align-items-center">
|
||||
<div class="col-md-4">
|
||||
<div class="page-title-box page-title-box-alt">
|
||||
<h4 class="page-title"><?= !empty($showPayment) ? 'Payment Logs' : 'Log Files' ?></h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8 text-md-right">
|
||||
<?php if (!empty($showPayment)): ?>
|
||||
<a href="<?= site_url('logs') ?>" class="btn btn-secondary">
|
||||
<i class="mdi mdi-arrow-left"></i> View All Logs
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a href="<?= site_url('logs?payment=1') ?>" class="btn btn-warning">
|
||||
<i class="mdi mdi-credit-card-outline"></i> View Payment Logs
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end page title -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
<?php if (session()->getFlashdata('message')): ?>
|
||||
<div class="alert alert-success"><?= esc(session()->getFlashdata('message')) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (session()->getFlashdata('error')): ?>
|
||||
<div class="alert alert-danger"><?= esc(session()->getFlashdata('error')) ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($showPayment)): ?>
|
||||
<p class="text-muted mb-3">
|
||||
Showing <strong><?= (int) $lineCount ?></strong> log <?= $lineCount === 1 ? 'entry' : 'entries' ?>
|
||||
containing <code>[PAYMENT]</code> across all log files.
|
||||
</p>
|
||||
|
||||
<?php if (empty($entries)): ?>
|
||||
<div class="alert alert-info mb-0">
|
||||
No payment log entries found. Payment activity is logged with the <code>[PAYMENT]</code> tag.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($entries as $entry): ?>
|
||||
<h5 class="mt-3 mb-2">
|
||||
<i class="mdi mdi-file-document-outline"></i> <?= esc($entry['file']) ?>
|
||||
<span class="badge badge-soft-warning"><?= count($entry['lines']) ?> entries</span>
|
||||
<a href="<?= site_url('logs/view/' . $entry['file'] . '?payment=1') ?>" class="btn btn-sm btn-outline-warning ml-2">
|
||||
Open File
|
||||
</a>
|
||||
</h5>
|
||||
<pre class="payment-log-block"><?= esc(implode("\n", $entry['lines'])) ?></pre>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<div class="table-responsive">
|
||||
<table id="datatable-buttons" class="table table-striped nowrap w-100">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>File Name</th>
|
||||
<th>Size</th>
|
||||
<th>Last Modified</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($files)): ?>
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-muted">No log files found.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($files as $file): ?>
|
||||
<tr>
|
||||
<td><?= esc($file['name']) ?></td>
|
||||
<td><span class="badge badge-soft-secondary"><?= esc($file['size']) ?></span></td>
|
||||
<td><?= esc($file['modified']) ?></td>
|
||||
<td>
|
||||
<a href="<?= site_url('logs/view/' . $file['name']) ?>" class="btn btn-sm btn-primary">
|
||||
<i class="mdi mdi-eye"></i> View
|
||||
</a>
|
||||
<a href="<?= site_url('logs/view/' . $file['name'] . '?payment=1') ?>" class="btn btn-sm btn-warning">
|
||||
<i class="mdi mdi-credit-card-outline"></i> Payment Logs
|
||||
</a>
|
||||
<a href="<?= site_url('logs/download/' . $file['name']) ?>" class="btn btn-sm btn-success">
|
||||
<i class="mdi mdi-download"></i> Download
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div><!-- end card-body -->
|
||||
</div><!-- end card -->
|
||||
</div><!-- end col -->
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
<style>
|
||||
.payment-log-block {
|
||||
background: #1e1e2e;
|
||||
color: #d4d4d4;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
max-height: 75vh;
|
||||
overflow: auto;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
font-size: 13px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
if ($('#datatable-buttons').length) {
|
||||
$('#datatable-buttons').DataTable({
|
||||
"order": [[2, 'desc']],
|
||||
"dom": '<"row mb-3"<"col-md-6 d-flex align-items-center"f><"col-md-6 d-flex justify-content-end">>rtip',
|
||||
columnDefs: [
|
||||
{ orderable: false, targets: [3] }
|
||||
]
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
41
app/Views/logviewer/view.php
Normal file
41
app/Views/logviewer/view.php
Normal file
@ -0,0 +1,41 @@
|
||||
<!-- start page title -->
|
||||
<div class="row d-flex align-items-center">
|
||||
<div class="col-md-8">
|
||||
<div class="page-title-box page-title-box-alt">
|
||||
<h4 class="page-title">
|
||||
<?= !empty($showPayment) ? 'Payment Logs' : 'Viewing Log' ?>: <?= esc($filename) ?>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 text-md-right">
|
||||
<a href="<?= site_url('logs') ?>" class="btn btn-secondary">
|
||||
<i class="mdi mdi-arrow-left"></i> Back to Log Files
|
||||
</a>
|
||||
<?php if (!empty($showPayment)): ?>
|
||||
<a href="<?= site_url('logs/view/' . $filename) ?>" class="btn btn-primary">
|
||||
<i class="mdi mdi-eye"></i> View Full Log
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a href="<?= site_url('logs/view/' . $filename . '?payment=1') ?>" class="btn btn-warning">
|
||||
<i class="mdi mdi-credit-card-outline"></i> View Payment Logs
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end page title -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<?php if (!empty($showPayment) && $content === ''): ?>
|
||||
<div class="alert alert-info mb-0">
|
||||
No payment log entries found in this file.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<pre style="background:#1e1e2e; color:#d4d4d4; padding:20px; border-radius:8px; max-height:75vh; overflow:auto; white-space:pre-wrap; word-wrap:break-word; font-size:13px;"><?= esc($content) ?></pre>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -8,6 +8,7 @@
|
||||
<th><b>ORDER ID</b></th>
|
||||
<th style="text-align: left;">Payment Status</th>
|
||||
<th><b>Amount</b></th>
|
||||
<th><b>Action</b></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="custom-tbody">
|
||||
@ -20,6 +21,15 @@
|
||||
<td style="text-align: left;"><?= isset($row['order_id'])?$row['order_id']:"-"?></td>
|
||||
<td style="text-align: left;"><?= isset($row['payment_status'])?$row['payment_status']:"-" ?></td>
|
||||
<td style="text-align: right;"><?= isset($row['amount'])?$row['amount']:"-"?></td>
|
||||
<td style="text-align: center;">
|
||||
<?php if (($row['payment_status'] ?? '') === 'Not Received' && ! empty($row['order_id'])) { ?>
|
||||
<button type="button" class="btn btn-sm btn-warning reconcile-btn" data-order-id="<?= esc($row['order_id']) ?>">
|
||||
Sync with Paytm
|
||||
</button>
|
||||
<?php } else { ?>
|
||||
-
|
||||
<?php } ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
|
||||
@ -157,6 +157,35 @@
|
||||
dom: 'Bfrtip', // 'B' means Buttons
|
||||
buttons: [],
|
||||
});
|
||||
|
||||
$('#datatable-buttons').off('click', '.reconcile-btn').on('click', '.reconcile-btn', function() {
|
||||
var orderId = $(this).data('order-id');
|
||||
var $btn = $(this);
|
||||
if (!confirm('Verify this payment with Paytm and record the renewal if paid?')) {
|
||||
return;
|
||||
}
|
||||
$btn.prop('disabled', true).text('Syncing...');
|
||||
$.ajax({
|
||||
url: "<?= base_url('payment_reconcile') ?>",
|
||||
method: "POST",
|
||||
data: { order_id: orderId },
|
||||
dataType: "json",
|
||||
success: function(response) {
|
||||
alert(response.message);
|
||||
if (response.status) {
|
||||
var daterange = $('#daterange').val();
|
||||
var status = $('#statusSwitch').is(':checked') ? 1 : 0;
|
||||
getTableData(daterange, status);
|
||||
} else {
|
||||
$btn.prop('disabled', false).text('Sync with Paytm');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('Could not connect to the server. Please try again.');
|
||||
$btn.prop('disabled', false).text('Sync with Paytm');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getPreviousMonthDateRange() {
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<link href="<?= base_url() . "public/assets/libs/bootstrap-datepicker/css/bootstrap-datepicker.min.css" ?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?= base_url() . "public/assets/libs/bootstrap-daterangepicker/daterangepicker.css" ?>" rel="stylesheet" type="text/css">
|
||||
<link href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>">
|
||||
<script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>
|
||||
|
||||
<!-- third party css end -->
|
||||
|
||||
@ -306,6 +306,10 @@
|
||||
<a href="<?= base_url() . "report_userwise_and_eventwise"; ?>">User Eventwise-Sales</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="<?= base_url() . "logs"; ?>">Logs</a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
BIN
public/systemflow.png
Normal file
BIN
public/systemflow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 555 KiB |
Loading…
Reference in New Issue
Block a user