vb_book/app/Controllers/Payment.php

694 lines
28 KiB
PHP

<?php
namespace App\Controllers;
use App\Models\BooksModel;
use App\Models\CustomerModel;
use App\Models\InvoiceModel;
use App\Models\TransactionModel;
use App\Models\SubscriptionModel;
use App\Models\AuthenticationModel;
use App\Models\PaymentStatusModel;
use App\Helpers\SendSMSHelper;
require_once('vendor/autoload.php');
define('PROJECT', 'vendor/paytm/paytm-pg');
class Payment extends BaseController
{
protected $paymentModel;
protected $sendSMSHelper;
public function __construct() {
helper('encdec_paytm');
$this->paymentModel = new PaymentStatusModel();
$this->sendSMSHelper = new SendSMSHelper();
}
public function index($membership_id = null)
{
helper('session');
$model = new CustomerModel();
$model2 = new SubscriptionModel();
$bookModel = new BooksModel();
$session_uid = get_logged_user_id();
$auth_model = new AuthenticationModel();
$details = $auth_model->getheringDetailsForHeader($session_uid);
$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");
if ($membership_id != null){
$customer_id = $model2->select('customer_id')->where('membership_id',$membership_id)->first();
$customer_details = $model->get_customer_details_by_customer_id($customer_id);
$scheme = $model2->get_subscription_details_by_membership_id($membership_id);
//var_dump($customer_details);die();
$book_id = env('RENEWAL_SCHEME_ID');
$price = $bookModel->select('price')->where('book_id', $book_id)->first();
$amount = $price['price'];
log_message('debug','amount is '.$amount);
$response = [
'customer_details' => $customer_details,
'scheme' => $scheme,
'membership_id' =>$membership_id,
'CustomerID' =>$customer_id,
'amount' =>$amount
];
$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");
log_message('info', '[PAYMENT] Customer opened renewal page for membership ' . $membership_id . ', amount Rs.' . $amount);
return view('subscription_renewal',$response);
}
else{
if ($this->request->getMethod() == 'get') {
$membership_id = $this->request->getGet('ID');
if (isset($membership_id) && !empty($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);
$scheme = $model2->get_subscription_details_by_membership_id($membership_id);
//var_dump($customer_details);die();
$book_id = env('RENEWAL_SCHEME_ID');
$price = $bookModel->select('price')->where('book_id', $book_id)->first();
$amount = $price['price'];
log_message('debug','amount is '.$amount);
$response = [
'customer_details' => $customer_details,
'scheme' => $scheme,
'membership_id' =>$membership_id,
'CustomerID' =>$customer_id,
'amount' =>$amount
];
$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");
}
log_message('info', '[PAYMENT] Customer opened renewal page for membership ' . ($membership_id ?? ''));
return view('subscription_renewal',$response);
}
else {
//echo "inside else";die();
$membership_id = $this->request->getPost('membership_id');
$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('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'];
$response = [
'customer_details' => $customer_details,
'scheme' => $scheme,
'CustomerID' =>$customer_id,
'amount' =>$amount
];
return $this->response->setJSON($response);
}
}
}
public function pay()
{
// $payment_model = new PaymentStatusModel();
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$payment_method = preg_match('/mobile/i', $userAgent) ? "mobile" : 'website';
$data = $_POST;
$membership_id = $this->request->getPost('membership_id');
$paramList = array();
$CUST_ID = (string) $this->request->getPost("CustomerID");
$ORDER_ID = (string) uniqid($CUST_ID . "_".$membership_id."_");
$CHANNEL_ID = ($payment_method == "mobile") ? (string) env('Channel_ID_Mobile') : (string) env('Channel_ID_WEB');
$TXN_AMOUNT = (string) $this->request->getPost("amount");
$paramList["MID"] = (string) env('Merchant_ID');
$paramList["ORDER_ID"] = $ORDER_ID;
$paramList["CUST_ID"] = $CUST_ID;
$paramList["INDUSTRY_TYPE_ID"] = env('Industry_Type');
$paramList["CHANNEL_ID"] = $CHANNEL_ID;
$paramList["TXN_AMOUNT"] = $TXN_AMOUNT;
$paramList["WEBSITE"] = (string) env('Website');
$paramList["CALLBACK_URL"] = (string) base_url('tresponse');
$checkSum = getChecksumFromArray($paramList, env('Merchant_Key'));
$data['checkSum'] = $checkSum;
$data['paramList'] = $paramList;
$decryptedChecksum = verifychecksum_e($data['paramList'], env('Merchant_Key'),$data['checkSum']);
$payment_status_data = [
'customer_id' => $CUST_ID,
'membership_id' => $membership_id,
'order_id' => $ORDER_ID,
'scheme_id' => env('RENEWAL_SCHEME_ID'),
'amount' => $TXN_AMOUNT,
'device' => $payment_method == "mobile"? "Mobile":"Web",
'payment_status'=> 'Not Received'
];
$result = $this->paymentModel->insert($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('info', '[PAYMENT] Redirecting customer to Paytm gateway for order ' . $ORDER_ID);
return view('/tresponse', $data);
}
public function tresponse() {
$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') {
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(){
$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'),
'is_active' => 1,
];
$orderId = $paramList['ORDERID'] ?? '';
if (! empty($orderId)) {
log_message('info', '[PAYMENT] Customer reached payment failure page for order ' . $orderId . ', status ' . ($paramList['STATUS'] ?? 'unknown'));
}
$this->updateFailedPayment($paramList);
return view('/payment_failure');
}
public function payment_process() {
$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 = 'paytm';
$currentDate = date('Y-m-d');
$db = \Config\Database::connect();
$subModel = new SubscriptionModel();
$bookModel = new BooksModel();
$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'] ?? ($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)));
}
$tsubscription = date('Y-m-d', strtotime('+1 year', strtotime($fsubscription)));
$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();
$invoice->approve_notifications((int) $invoice_id['invoice_id'], ['msg_mail' => 1]);
$invoiceController = new Invoice();
$membership_id = $invoiceController->generate_membership_id(6);
$subscription = $subModel->select('sub_id')
->where('membership_id', $past_membership_id)
->first();
$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->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->getInsertID();
$paymentRow = $this->paymentModel->select('id')->where('order_id', $orderId)->first();
if ($paymentRow !== null) {
$this->paymentModel->update($paymentRow['id'], [
'status' => $insertId,
'payment_status' => 'Success',
]);
}
$db->transComplete();
if ($db->transStatus() === false) {
throw new \RuntimeException('Database transaction failed while saving renewal');
}
log_message('info', '[PAYMENT] Renewal completed — order ' . $orderId . ', invoice ' . $invoice_number . ', new membership ' . $membership_id . ', customer ' . $customer_id);
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) {
$next_id_string = $filtered_data[0]['next_id'];
$left_pad_string = $filtered_data[0]['left_pad'];
$prefix_string = $financial_year;
$left_pad_numeric = (int)$left_pad_string;
$next_id_numeric = (int)$next_id_string;
$padded_id = str_pad($next_id_string, $left_pad_numeric, '0', STR_PAD_LEFT);
$serial_number = $prefix_string . '-' . $padded_id;
$next_id_numeric++;
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');
}
public function listLogs()
{
$logPath = WRITEPATH . 'logs/';
$logs = [];
// Check if the log directory exists
if (is_dir($logPath)) {
$files = array_diff(scandir($logPath), ['.', '..']); // Exclude '.' and '..'
$files = array_reverse($files);
foreach ($files as $file) {
if (is_file($logPath . $file)) {
$logs[] = $file; // Add log files to the list
}
}
}
$data['logs'] = $logs;
$data['server_details'] = get_server_details();
$data['page_name'] = 'list_log';
// $data['company_name'] = "Vijayabharatham Prasuram";
// $data['company_short_name']= "VP";
// Pass log files to the view
return view('log_view', $data);
}
public function downloadLog($fileName)
{
$logPath = WRITEPATH . 'logs/' . $fileName;
// Check if the requested file exists
if (file_exists($logPath)) {
return $this->response->download($logPath, null)->setFileName($fileName);
}
// Redirect back with an error if file doesn't exist
return redirect()->back()->with('error', 'Log file not found.');
}
public function viewLog($fileName)
{
$logPath = WRITEPATH . 'logs/' . $fileName;
if (file_exists($logPath)) {
$content = file_get_contents($logPath);
$data['fileName'] = $fileName;
$data['content'] = $content;
$data['server_details'] = get_server_details();
$data['page_name'] = 'View Log';
// $data['company_name'] = "Vijayabharatham Prasuram";
// $data['company_short_name']= "VP";
return view('log_content_view', $data);
}
return redirect()->back()->with('error', 'Log file not found.');
}
public function paymentStatus(){
if ($this->request->is('get')){
$data['page_name'] = "Payment Status";
$data['selected_data'] = "";
$data['payment_status'] = $this->paymentModel->where('is_active',1)->findAll();
// dd($data);
return $this->render_page('payment_status_view',$data);
}else{
$received_data = $this->request->getPost();
$dateParts = explode(' - ', $received_data['dateRange']);
$status = $received_data['status'];
$fromDate = $dateParts[0];
$toDate = $dateParts[1];
// Update date conversion format using the global namespace
$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);
$html = view('payment_status_table',$payment_data);
$data['selected_data'] = $received_data['dateRange'];
// $data = "";
return $this->response->setJSON(['status'=> true,'data' => $data,"html" => $html]);
}
}
// public function testSMS(){
// $mobile_number = '916382156701';
// $name = "Srinivas";
// $expiryDate = "10/10/2025";
// $link = "https://bit.ly/44Iy4Zm";
// // Exactly matching the approved template
// $message = "Hi {$name}, your subscription for Pusthakam scheme is about to expire on {$expiryDate}. Renew now to continue enjoying our books for one more year. Tap here to renew: {$link} -Vijayabharatham Prasuram";
// $status = $this->sendSMSHelper->sendSMS($message,$mobile_number);
// echo $status;
// }
}