694 lines
28 KiB
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;
|
|
// }
|
|
|
|
|
|
}
|
|
|