1 changed files with 480 additions and 480 deletions
@ -1,481 +1,481 @@ |
|||||
<?php |
|
||||
|
|
||||
/** |
|
||||
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/) |
|
||||
* |
|
||||
* Payment Gateway PipraPay |
|
||||
* Fixed Version with Auto-Verify Support |
|
||||
**/ |
|
||||
|
|
||||
// PipraPay Configuration
|
|
||||
$piprapay_config = [ |
|
||||
'api_key' => '186691761268d6f85579c84532234998155044887968d6f85579c891167595247', |
|
||||
'base_url' => 'https://pay.wifibills.com/api', |
|
||||
'gateway_name' => 'PipraPay' |
|
||||
]; |
|
||||
|
|
||||
function piprapay_validate_config() |
|
||||
{ |
|
||||
global $piprapay_config; |
|
||||
} |
|
||||
|
|
||||
function piprapay_show_config() |
|
||||
{ |
|
||||
global $ui, $piprapay_config; |
|
||||
|
|
||||
$ui->assign('_title', $piprapay_config['gateway_name'] . ' - Payment Gateway'); |
|
||||
|
|
||||
echo ' |
|
||||
<div class="row"> |
|
||||
<div class="col-sm-12 col-md-12"> |
|
||||
<div class="panel panel-primary panel-hovered panel-stacked mb30"> |
|
||||
<div class="panel-heading">' . $piprapay_config['gateway_name'] . ' Configuration</div> |
|
||||
<div class="panel-body"> |
|
||||
<div class="alert alert-info"> |
|
||||
<h4><i class="fa fa-info-circle"></i> ' . $piprapay_config['gateway_name'] . ' Gateway</h4> |
|
||||
<p>This payment gateway is pre-configured and ready to use.</p> |
|
||||
</div> |
|
||||
|
|
||||
<div class="form-group"> |
|
||||
<label class="col-md-3 control-label">API Key</label> |
|
||||
<div class="col-md-9"> |
|
||||
<input type="text" class="form-control" readonly value="' . $piprapay_config['api_key'] . '"> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div class="form-group"> |
|
||||
<label class="col-md-3 control-label">Base URL</label> |
|
||||
<div class="col-md-9"> |
|
||||
<input type="text" class="form-control" readonly value="' . $piprapay_config['base_url'] . '"> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div class="form-group"> |
|
||||
<label class="col-md-3 control-label">Callback URL</label> |
|
||||
<div class="col-md-9"> |
|
||||
<input type="text" class="form-control" readonly value="' . U . 'callback/piprapay"> |
|
||||
<span class="help-block">PipraPay will redirect users to this URL after payment</span> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div class="alert alert-success"> |
|
||||
<strong><i class="fa fa-check-circle"></i> Gateway Active</strong><br> |
|
||||
' . $piprapay_config['gateway_name'] . ' is ready to accept payments. |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div>'; |
|
||||
} |
|
||||
|
|
||||
function piprapay_save_config() |
|
||||
{ |
|
||||
global $admin; |
|
||||
_log('[' . $admin['username'] . ']: ' . Lang::T('PipraPay_Configuration_Viewed'), 'Admin', $admin['id']); |
|
||||
r2(U . 'paymentgateway/piprapay', 's', Lang::T('PipraPay_is_preconfigured')); |
|
||||
} |
|
||||
|
|
||||
function piprapay_create_transaction($trx, $user) |
|
||||
{ |
|
||||
global $piprapay_config; |
|
||||
|
|
||||
try { |
|
||||
// Use direct URL format to avoid routing issues
|
|
||||
$success_url = APP_URL . '/?_route=callback/piprapay&invoice_id=' . $trx['id']; |
|
||||
$cancel_url = U . 'order/view/' . $trx['id']; |
|
||||
|
|
||||
// Create simple metadata
|
|
||||
$metadata = [ |
|
||||
'invoice_id' => $trx['id'], |
|
||||
'customer_id' => $user['id'], |
|
||||
'customer_name' => $user['fullname'] ?: $user['username'], |
|
||||
'plan_id' => $trx['plan_id'] |
|
||||
]; |
|
||||
|
|
||||
// Payload with ALL required fields
|
|
||||
$payload = [ |
|
||||
'full_name' => $user['fullname'] ?: $user['username'], |
|
||||
'email_mobile' => $user['email'] ?: ($user['phonenumber'] ?: 'user@example.com'), |
|
||||
'amount' => number_format($trx['price'], 2, '.', ''), |
|
||||
'redirect_url' => $success_url, |
|
||||
'return_type' => 'GET', |
|
||||
'cancel_url' => $cancel_url, |
|
||||
'webhook_url' => U . 'callback/piprapay', |
|
||||
'currency' => 'BDT', |
|
||||
'metadata' => $metadata |
|
||||
]; |
|
||||
|
|
||||
$headers = [ |
|
||||
'accept: application/json', |
|
||||
'content-type: application/json', |
|
||||
'mh-piprapay-api-key: ' . $piprapay_config['api_key'] |
|
||||
]; |
|
||||
|
|
||||
$create_charge_url = $piprapay_config['base_url'] . '/create-charge'; |
|
||||
|
|
||||
_log("PipraPay Create Transaction Request: " . json_encode($payload), 'PipraPay'); |
|
||||
|
|
||||
// Make the API call
|
|
||||
$response = Http::postJsonData($create_charge_url, $payload, $headers); |
|
||||
$result = json_decode($response, true); |
|
||||
|
|
||||
_log("PipraPay Create Transaction Response: " . $response, 'PipraPay'); |
|
||||
|
|
||||
// Check for success using the correct response format
|
|
||||
if (isset($result['status']) && $result['status'] === true) { |
|
||||
if (isset($result['pp_url'])) { |
|
||||
$transaction_id = $result['pp_id'] ?? uniqid(); |
|
||||
|
|
||||
// Save payment gateway transaction
|
|
||||
$d = ORM::for_table('tbl_payment_gateway') |
|
||||
->where('username', $user['username']) |
|
||||
->where('status', 1) |
|
||||
->find_one(); |
|
||||
if (!$d) { |
|
||||
$d = ORM::for_table('tbl_payment_gateway')->create(); |
|
||||
$d->username = $user['username']; |
|
||||
$d->user_id = $user['id']; |
|
||||
$d->created_date = date('Y-m-d H:i:s'); |
|
||||
} |
|
||||
$d->gateway_trx_id = $transaction_id; |
|
||||
$d->plan_id = $trx['plan_id']; |
|
||||
$d->plan_name = $trx['plan_name']; |
|
||||
$d->routers_id = $trx['routers']; |
|
||||
$d->routers = $trx['name']; |
|
||||
$d->price = $trx['price']; |
|
||||
$d->pg_url_payment = $result['pp_url']; |
|
||||
$d->pg_request = json_encode($result); |
|
||||
$d->expired_date = date('Y-m-d H:i:s', strtotime('+24 HOURS')); |
|
||||
$d->gateway = 'piprapay'; |
|
||||
$d->trx_invoice = $trx['id']; |
|
||||
$d->status = 1; |
|
||||
$d->save(); |
|
||||
|
|
||||
// Update transaction with gateway_trx_id
|
|
||||
$trx->gateway_trx_id = $transaction_id; |
|
||||
$trx->save(); |
|
||||
|
|
||||
_log("PipraPay - Created payment gateway record ID: " . $d->id(), 'PipraPay'); |
|
||||
|
|
||||
// Redirect to payment gateway
|
|
||||
header('Location: ' . $result['pp_url']); |
|
||||
exit(); |
|
||||
} else { |
|
||||
$error_message = 'Payment URL not received from gateway'; |
|
||||
_log("PipraPay Error: " . $error_message, 'PipraPay'); |
|
||||
r2(U . 'order/package', 'e', Lang::T("Failed to create transaction. ") . $error_message); |
|
||||
} |
|
||||
} else { |
|
||||
$error_message = $result['message'] ?? 'Failed to create payment'; |
|
||||
_log("PipraPay API Error: " . $error_message, 'PipraPay'); |
|
||||
r2(U . 'order/package', 'e', Lang::T("Failed to create transaction. ") . $error_message); |
|
||||
} |
|
||||
} catch (Exception $e) { |
|
||||
_log("PipraPay Exception: " . $e->getMessage(), 'PipraPay'); |
|
||||
r2(U . 'order/package', 'e', Lang::T("System error occurred. Please try again.")); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
function piprapay_get_status($trx, $user) |
|
||||
{ |
|
||||
global $piprapay_config; |
|
||||
|
|
||||
try { |
|
||||
if (empty($trx['gateway_trx_id'])) { |
|
||||
_log("PipraPay Verification - No gateway transaction ID", 'PipraPay'); |
|
||||
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("No transaction ID found for verification.")); |
|
||||
} |
|
||||
|
|
||||
// Use correct endpoint and method
|
|
||||
$verify_url = $piprapay_config['base_url'] . '/verify-payments'; |
|
||||
|
|
||||
// Use correct field name 'pp_id' instead of 'transaction_id'
|
|
||||
$payload = [ |
|
||||
'pp_id' => $trx['gateway_trx_id'] |
|
||||
]; |
|
||||
|
|
||||
$headers = [ |
|
||||
'accept: application/json', |
|
||||
'content-type: application/json', |
|
||||
'mh-piprapay-api-key: ' . $piprapay_config['api_key'] |
|
||||
]; |
|
||||
|
|
||||
_log("PipraPay Verification Request - PP ID: " . $trx['gateway_trx_id'], 'PipraPay'); |
|
||||
|
|
||||
$response = Http::postJsonData($verify_url, $payload, $headers); |
|
||||
$result = json_decode($response, true); |
|
||||
|
|
||||
_log("PipraPay Verification Raw Response: " . $response, 'PipraPay'); |
|
||||
_log("PipraPay Verification Parsed Response: " . json_encode($result), 'PipraPay'); |
|
||||
|
|
||||
// Check if API call was successful
|
|
||||
if (!$result || !is_array($result)) { |
|
||||
_log("PipraPay Verification - Invalid response format", 'PipraPay'); |
|
||||
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Invalid response from payment gateway.")); |
|
||||
} |
|
||||
|
|
||||
// Check if transaction is already paid
|
|
||||
if ($trx['status'] == 2) { |
|
||||
_log("PipraPay Verification - Transaction already paid", 'PipraPay'); |
|
||||
r2(U . "order/view/" . $trx['id'], 's', Lang::T("Transaction has been paid.")); |
|
||||
} |
|
||||
|
|
||||
// Check for success - PipraPay API might have different response structure
|
|
||||
$is_paid = false; |
|
||||
$payment_status = ''; |
|
||||
$payment_method = ''; |
|
||||
$payment_channel = ''; |
|
||||
|
|
||||
// Check multiple possible response formats from PipraPay
|
|
||||
if (isset($result['status']) && $result['status'] === true) { |
|
||||
// Format 1: Direct status in response
|
|
||||
if (isset($result['payment_status'])) { |
|
||||
$payment_status = strtolower(trim($result['payment_status'])); |
|
||||
$is_paid = in_array($payment_status, ['success', 'completed', 'paid', 'successful', 'processed', 'complete']); |
|
||||
} |
|
||||
// Format 2: Data array with status
|
|
||||
elseif (isset($result['data']['payment_status'])) { |
|
||||
$payment_status = strtolower(trim($result['data']['payment_status'])); |
|
||||
$is_paid = in_array($payment_status, ['success', 'completed', 'paid', 'successful', 'processed', 'complete']); |
|
||||
} |
|
||||
// Format 3: Check if payment is verified directly
|
|
||||
elseif (isset($result['is_paid']) && $result['is_paid'] === true) { |
|
||||
$is_paid = true; |
|
||||
$payment_status = 'paid'; |
|
||||
} |
|
||||
// Format 4: Check payment object
|
|
||||
elseif (isset($result['payment']['status'])) { |
|
||||
$payment_status = strtolower(trim($result['payment']['status'])); |
|
||||
$is_paid = in_array($payment_status, ['success', 'completed', 'paid', 'successful', 'processed', 'complete']); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Extract payment method and channel if available
|
|
||||
if (isset($result['payment_method'])) { |
|
||||
$payment_method = $result['payment_method']; |
|
||||
} |
|
||||
if (isset($result['payment_channel'])) { |
|
||||
$payment_channel = $result['payment_channel']; |
|
||||
} |
|
||||
if (isset($result['data']['payment_method'])) { |
|
||||
$payment_method = $result['data']['payment_method']; |
|
||||
} |
|
||||
if (isset($result['data']['payment_channel'])) { |
|
||||
$payment_channel = $result['data']['payment_channel']; |
|
||||
} |
|
||||
|
|
||||
_log("PipraPay Payment Analysis - Status: " . $payment_status . ", Is Paid: " . ($is_paid ? 'Yes' : 'No'), 'PipraPay'); |
|
||||
|
|
||||
if ($is_paid) { |
|
||||
_log("PipraPay Payment Successful - Activating package", 'PipraPay'); |
|
||||
|
|
||||
// Update payment gateway record
|
|
||||
$pg_trx = ORM::for_table('tbl_payment_gateway') |
|
||||
->where('gateway_trx_id', $trx['gateway_trx_id']) |
|
||||
->find_one(); |
|
||||
|
|
||||
if ($pg_trx) { |
|
||||
$pg_trx->pg_paid_response = json_encode($result); |
|
||||
$pg_trx->payment_method = $payment_method ?: $piprapay_config['gateway_name']; |
|
||||
$pg_trx->payment_channel = $payment_channel ?: $piprapay_config['gateway_name']; |
|
||||
$pg_trx->paid_date = date('Y-m-d H:i:s'); |
|
||||
$pg_trx->status = 2; // Paid
|
|
||||
$pg_trx->trx_invoice = $trx['id']; |
|
||||
$pg_trx->save(); |
|
||||
_log("PipraPay - Updated payment gateway record ID: " . $pg_trx['id'] . " with status 2", 'PipraPay'); |
|
||||
} |
|
||||
|
|
||||
// Activate user package
|
|
||||
if (!Package::rechargeUser($user['id'], $trx['routers'], $trx['plan_id'], $trx['gateway'], $piprapay_config['gateway_name'])) { |
|
||||
_log("PipraPay - Failed to activate package for user: " . $user['id'], 'PipraPay'); |
|
||||
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Failed to activate your Package, try again later.")); |
|
||||
} |
|
||||
|
|
||||
// Update transaction
|
|
||||
$trx->pg_paid_response = json_encode($result); |
|
||||
$trx->payment_method = $payment_method ?: $piprapay_config['gateway_name']; |
|
||||
$trx->payment_channel = $payment_channel ?: $piprapay_config['gateway_name']; |
|
||||
$trx->paid_date = date('Y-m-d H:i:s'); |
|
||||
$trx->status = 2; |
|
||||
$trx->save(); |
|
||||
|
|
||||
_log("PipraPay - Transaction marked as paid: " . $trx['id'], 'PipraPay'); |
|
||||
r2(U . "order/view/" . $trx['id'], 's', Lang::T("Payment successful! Your package has been activated.")); |
|
||||
} else { |
|
||||
_log("PipraPay Payment Not Successful - Status: " . $payment_status, 'PipraPay'); |
|
||||
r2(U . "order/view/" . $trx['id'], 'w', Lang::T("Payment status: ") . $payment_status); |
|
||||
} |
|
||||
} catch (Exception $e) { |
|
||||
_log("PipraPay Verification Exception: " . $e->getMessage(), 'PipraPay'); |
|
||||
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("System error during verification.")); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// REQUIRED: This function is called by the callback router
|
|
||||
function piprapay_payment_notification() |
|
||||
{ |
|
||||
global $piprapay_config; |
|
||||
|
|
||||
_log("=== PIPRAPAY PAYMENT NOTIFICATION CALLED ===", 'PipraPay'); |
|
||||
_log("GET Parameters: " . json_encode($_GET), 'PipraPay'); |
|
||||
_log("POST Parameters: " . json_encode($_POST), 'PipraPay'); |
|
||||
_log("Request Method: " . $_SERVER['REQUEST_METHOD'], 'PipraPay'); |
|
||||
_log("Raw Query String: " . ($_SERVER['QUERY_STRING'] ?? 'NONE'), 'PipraPay'); |
|
||||
|
|
||||
// Call the main callback handler
|
|
||||
piprapay_callback_handler(); |
|
||||
} |
|
||||
|
|
||||
// Enhanced callback handler that handles both user redirects and auto-verify
|
|
||||
function piprapay_callback_handler() |
|
||||
{ |
|
||||
global $piprapay_config; |
|
||||
|
|
||||
_log("PipraPay Callback Handler Started", 'PipraPay'); |
|
||||
|
|
||||
try { |
|
||||
// SCENARIO 1: Handle POST requests (Auto-verify/Webhook)
|
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') { |
|
||||
_log("PipraPay - Processing POST Request", 'PipraPay'); |
|
||||
|
|
||||
// Handle auto-verify requests from system
|
|
||||
if (isset($_POST['action']) && $_POST['action'] === 'auto_verify') { |
|
||||
_log("PipraPay - Auto-verify request detected", 'PipraPay'); |
|
||||
|
|
||||
// Find the most recent unpaid transaction
|
|
||||
$pg_trx = ORM::for_table('tbl_payment_gateway') |
|
||||
->where('status', 1) // Unpaid status
|
|
||||
->where('gateway', 'piprapay') |
|
||||
->order_by_desc('id') |
|
||||
->find_one(); |
|
||||
|
|
||||
if ($pg_trx && !empty($pg_trx['trx_invoice'])) { |
|
||||
$invoice_id = $pg_trx['trx_invoice']; |
|
||||
_log("PipraPay - Found unpaid transaction for auto-verify: " . $invoice_id, 'PipraPay'); |
|
||||
|
|
||||
$trx = ORM::for_table('tbl_transactions')->find_one($invoice_id); |
|
||||
$user = ORM::for_table('tbl_customers')->find_one($pg_trx['user_id']); |
|
||||
|
|
||||
if ($trx && $user) { |
|
||||
_log("PipraPay - Auto-verifying transaction: " . $invoice_id, 'PipraPay'); |
|
||||
piprapay_get_status($trx, $user); |
|
||||
} else { |
|
||||
_log("PipraPay - Transaction or user not found for auto-verify", 'PipraPay'); |
|
||||
} |
|
||||
} else { |
|
||||
_log("PipraPay - No unpaid transactions found for auto-verify", 'PipraPay'); |
|
||||
} |
|
||||
|
|
||||
// Return success for auto-verify
|
|
||||
http_response_code(200); |
|
||||
echo json_encode(['status' => 'processed']); |
|
||||
exit; |
|
||||
} |
|
||||
|
|
||||
// Handle PipraPay webhook data
|
|
||||
if (!empty($_POST['pp_id']) || !empty($_POST['transaction_id'])) { |
|
||||
$transaction_id = $_POST['pp_id'] ?? $_POST['transaction_id'] ?? ''; |
|
||||
_log("PipraPay - Webhook with transaction ID: " . $transaction_id, 'PipraPay'); |
|
||||
|
|
||||
if (!empty($transaction_id)) { |
|
||||
// Find payment gateway record
|
|
||||
$pg_trx = ORM::for_table('tbl_payment_gateway') |
|
||||
->where('gateway_trx_id', $transaction_id) |
|
||||
->find_one(); |
|
||||
|
|
||||
if ($pg_trx && !empty($pg_trx['trx_invoice'])) { |
|
||||
// Find transaction and user
|
|
||||
$trx = ORM::for_table('tbl_transactions')->find_one($pg_trx['trx_invoice']); |
|
||||
$user = ORM::for_table('tbl_customers')->find_one($pg_trx['user_id']); |
|
||||
|
|
||||
if ($trx && $user) { |
|
||||
_log("PipraPay Webhook - Processing transaction: " . $transaction_id, 'PipraPay'); |
|
||||
piprapay_get_status($trx, $user); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Return success for webhook
|
|
||||
http_response_code(200); |
|
||||
echo json_encode(['status' => 'success']); |
|
||||
exit; |
|
||||
} |
|
||||
|
|
||||
// Default response for POST requests
|
|
||||
http_response_code(200); |
|
||||
echo json_encode(['status' => 'received']); |
|
||||
exit; |
|
||||
} |
|
||||
|
|
||||
// SCENARIO 2: Handle GET requests (User redirects)
|
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET') { |
|
||||
_log("PipraPay - Processing GET Request (User Redirect)", 'PipraPay'); |
|
||||
|
|
||||
// Parse invoice_id from multiple possible sources
|
|
||||
$invoice_id = null; |
|
||||
|
|
||||
// Method 1: Direct GET parameter
|
|
||||
if (isset($_GET['invoice_id'])) { |
|
||||
$invoice_id = intval($_GET['invoice_id']); |
|
||||
_log("PipraPay - Found invoice_id in GET: " . $invoice_id, 'PipraPay'); |
|
||||
} |
|
||||
// Method 2: Parse from query string
|
|
||||
else if (isset($_SERVER['QUERY_STRING'])) { |
|
||||
parse_str($_SERVER['QUERY_STRING'], $query_params); |
|
||||
if (isset($query_params['invoice_id'])) { |
|
||||
$invoice_id = intval($query_params['invoice_id']); |
|
||||
_log("PipraPay - Found invoice_id in query string: " . $invoice_id, 'PipraPay'); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if ($invoice_id) { |
|
||||
_log("PipraPay Callback - Processing Invoice ID: " . $invoice_id, 'PipraPay'); |
|
||||
|
|
||||
// Find the transaction
|
|
||||
$trx = ORM::for_table('tbl_transactions')->find_one($invoice_id); |
|
||||
if (!$trx) { |
|
||||
_log("PipraPay Callback - Transaction not found: " . $invoice_id, 'PipraPay'); |
|
||||
r2(U . 'order/package', 'e', Lang::T("Transaction not found.")); |
|
||||
} |
|
||||
|
|
||||
// Find user
|
|
||||
$user = ORM::for_table('tbl_customers')->find_one($trx['customer_id']); |
|
||||
if (!$user) { |
|
||||
_log("PipraPay Callback - User not found for transaction: " . $invoice_id, 'PipraPay'); |
|
||||
r2(U . 'order/package', 'e', Lang::T("User not found.")); |
|
||||
} |
|
||||
|
|
||||
// If we don't have gateway_trx_id, try to find it from payment_gateway table
|
|
||||
if (empty($trx['gateway_trx_id'])) { |
|
||||
$pg_trx = ORM::for_table('tbl_payment_gateway') |
|
||||
->where('username', $user['username']) |
|
||||
->where('status', 1) // Unpaid status
|
|
||||
->order_by_desc('id') |
|
||||
->find_one(); |
|
||||
|
|
||||
if ($pg_trx && !empty($pg_trx['gateway_trx_id'])) { |
|
||||
$trx->gateway_trx_id = $pg_trx['gateway_trx_id']; |
|
||||
$trx->save(); |
|
||||
_log("PipraPay Callback - Updated transaction with gateway_trx_id: " . $pg_trx['gateway_trx_id'], 'PipraPay'); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// Verify payment status via API
|
|
||||
piprapay_get_status($trx, $user); |
|
||||
} |
|
||||
|
|
||||
// Handle cancelled payment
|
|
||||
if (isset($_GET['status']) && $_GET['status'] == 'cancel') { |
|
||||
r2(U . 'order/package', 'w', Lang::T("Payment was cancelled. Please try again.")); |
|
||||
} |
|
||||
|
|
||||
// Default redirect if no invoice_id found
|
|
||||
_log("PipraPay Callback - No invoice_id found in GET request", 'PipraPay'); |
|
||||
r2(U . 'order/package', 'e', Lang::T("Payment verification failed - no transaction ID found.")); |
|
||||
} |
|
||||
|
|
||||
} catch (Exception $e) { |
|
||||
_log("PipraPay Callback Exception: " . $e->getMessage(), 'PipraPay'); |
|
||||
r2(U . 'order/package', 'e', Lang::T("System error occurred.")); |
|
||||
} |
|
||||
|
<?php |
||||
|
|
||||
|
/** |
||||
|
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/) |
||||
|
* |
||||
|
* Payment Gateway PipraPay |
||||
|
* Fixed Version with Auto-Verify Support |
||||
|
**/ |
||||
|
|
||||
|
// PipraPay Configuration
|
||||
|
$piprapay_config = [ |
||||
|
'api_key' => '186691761268d6f85579c84532234998155044887968d6f85579c891167595247', |
||||
|
'base_url' => 'https://pay.wifibills.com/api', |
||||
|
'gateway_name' => 'PipraPay' |
||||
|
]; |
||||
|
|
||||
|
function piprapay_validate_config() |
||||
|
{ |
||||
|
global $piprapay_config; |
||||
|
} |
||||
|
|
||||
|
function piprapay_show_config() |
||||
|
{ |
||||
|
global $ui, $piprapay_config; |
||||
|
|
||||
|
$ui->assign('_title', $piprapay_config['gateway_name'] . ' - Payment Gateway'); |
||||
|
|
||||
|
echo ' |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-12 col-md-12"> |
||||
|
<div class="panel panel-primary panel-hovered panel-stacked mb30"> |
||||
|
<div class="panel-heading">' . $piprapay_config['gateway_name'] . ' Configuration</div> |
||||
|
<div class="panel-body"> |
||||
|
<div class="alert alert-info"> |
||||
|
<h4><i class="fa fa-info-circle"></i> ' . $piprapay_config['gateway_name'] . ' Gateway</h4> |
||||
|
<p>This payment gateway is pre-configured and ready to use.</p> |
||||
|
</div> |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-3 control-label">API Key</label> |
||||
|
<div class="col-md-9"> |
||||
|
<input type="text" class="form-control" readonly value="' . $piprapay_config['api_key'] . '"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-3 control-label">Base URL</label> |
||||
|
<div class="col-md-9"> |
||||
|
<input type="text" class="form-control" readonly value="' . $piprapay_config['base_url'] . '"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-3 control-label">Callback URL</label> |
||||
|
<div class="col-md-9"> |
||||
|
<input type="text" class="form-control" readonly value="' . U . 'callback/piprapay"> |
||||
|
<span class="help-block">PipraPay will redirect users to this URL after payment</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="alert alert-success"> |
||||
|
<strong><i class="fa fa-check-circle"></i> Gateway Active</strong><br> |
||||
|
' . $piprapay_config['gateway_name'] . ' is ready to accept payments. |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div>'; |
||||
|
} |
||||
|
|
||||
|
function piprapay_save_config() |
||||
|
{ |
||||
|
global $admin; |
||||
|
_log('[' . $admin['username'] . ']: ' . Lang::T('PipraPay_Configuration_Viewed'), 'Admin', $admin['id']); |
||||
|
r2(U . 'paymentgateway/piprapay', 's', Lang::T('PipraPay_is_preconfigured')); |
||||
|
} |
||||
|
|
||||
|
function piprapay_create_transaction($trx, $user) |
||||
|
{ |
||||
|
global $piprapay_config; |
||||
|
|
||||
|
try { |
||||
|
// Use direct URL format to avoid routing issues
|
||||
|
$success_url = APP_URL . '/?_route=callback/piprapay&invoice_id=' . $trx['id']; |
||||
|
$cancel_url = U . 'order/view/' . $trx['id']; |
||||
|
|
||||
|
// Create simple metadata
|
||||
|
$metadata = [ |
||||
|
'invoice_id' => $trx['id'], |
||||
|
'customer_id' => $user['id'], |
||||
|
'customer_name' => $user['fullname'] ?: $user['username'], |
||||
|
'plan_id' => $trx['plan_id'] |
||||
|
]; |
||||
|
|
||||
|
// Payload with ALL required fields
|
||||
|
$payload = [ |
||||
|
'full_name' => $user['fullname'] ?: $user['username'], |
||||
|
'email_mobile' => $user['email'] ?: ($user['phonenumber'] ?: 'user@example.com'), |
||||
|
'amount' => number_format($trx['price'], 2, '.', ''), |
||||
|
'redirect_url' => $success_url, |
||||
|
'return_type' => 'GET', |
||||
|
'cancel_url' => $cancel_url, |
||||
|
'webhook_url' => U . 'callback/piprapay', |
||||
|
'currency' => 'BDT', |
||||
|
'metadata' => $metadata |
||||
|
]; |
||||
|
|
||||
|
$headers = [ |
||||
|
'accept: application/json', |
||||
|
'content-type: application/json', |
||||
|
'mh-piprapay-api-key: ' . $piprapay_config['api_key'] |
||||
|
]; |
||||
|
|
||||
|
$create_charge_url = $piprapay_config['base_url'] . '/create-charge'; |
||||
|
|
||||
|
_log("PipraPay Create Transaction Request: " . json_encode($payload), 'PipraPay'); |
||||
|
|
||||
|
// Make the API call
|
||||
|
$response = Http::postJsonData($create_charge_url, $payload, $headers); |
||||
|
$result = json_decode($response, true); |
||||
|
|
||||
|
_log("PipraPay Create Transaction Response: " . $response, 'PipraPay'); |
||||
|
|
||||
|
// Check for success using the correct response format
|
||||
|
if (isset($result['status']) && $result['status'] === true) { |
||||
|
if (isset($result['pp_url'])) { |
||||
|
$transaction_id = $result['pp_id'] ?? uniqid(); |
||||
|
|
||||
|
// Save payment gateway transaction
|
||||
|
$d = ORM::for_table('tbl_payment_gateway') |
||||
|
->where('username', $user['username']) |
||||
|
->where('status', 1) |
||||
|
->find_one(); |
||||
|
if (!$d) { |
||||
|
$d = ORM::for_table('tbl_payment_gateway')->create(); |
||||
|
$d->username = $user['username']; |
||||
|
$d->user_id = $user['id']; |
||||
|
$d->created_date = date('Y-m-d H:i:s'); |
||||
|
} |
||||
|
$d->gateway_trx_id = $transaction_id; |
||||
|
$d->plan_id = $trx['plan_id']; |
||||
|
$d->plan_name = $trx['plan_name']; |
||||
|
$d->routers_id = $trx['routers']; |
||||
|
$d->routers = $trx['name']; |
||||
|
$d->price = $trx['price']; |
||||
|
$d->pg_url_payment = $result['pp_url']; |
||||
|
$d->pg_request = json_encode($result); |
||||
|
$d->expired_date = date('Y-m-d H:i:s', strtotime('+24 HOURS')); |
||||
|
$d->gateway = 'piprapay'; |
||||
|
$d->trx_invoice = $trx['id']; |
||||
|
$d->status = 1; |
||||
|
$d->save(); |
||||
|
|
||||
|
// Update transaction with gateway_trx_id
|
||||
|
$trx->gateway_trx_id = $transaction_id; |
||||
|
$trx->save(); |
||||
|
|
||||
|
_log("PipraPay - Created payment gateway record ID: " . $d->id(), 'PipraPay'); |
||||
|
|
||||
|
// Redirect to payment gateway
|
||||
|
header('Location: ' . $result['pp_url']); |
||||
|
exit(); |
||||
|
} else { |
||||
|
$error_message = 'Payment URL not received from gateway'; |
||||
|
_log("PipraPay Error: " . $error_message, 'PipraPay'); |
||||
|
r2(U . 'order/package', 'e', Lang::T("Failed to create transaction. ") . $error_message); |
||||
|
} |
||||
|
} else { |
||||
|
$error_message = $result['message'] ?? 'Failed to create payment'; |
||||
|
_log("PipraPay API Error: " . $error_message, 'PipraPay'); |
||||
|
r2(U . 'order/package', 'e', Lang::T("Failed to create transaction. ") . $error_message); |
||||
|
} |
||||
|
} catch (Exception $e) { |
||||
|
_log("PipraPay Exception: " . $e->getMessage(), 'PipraPay'); |
||||
|
r2(U . 'order/package', 'e', Lang::T("System error occurred. Please try again.")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function piprapay_get_status($trx, $user) |
||||
|
{ |
||||
|
global $piprapay_config; |
||||
|
|
||||
|
try { |
||||
|
if (empty($trx['gateway_trx_id'])) { |
||||
|
_log("PipraPay Verification - No gateway transaction ID", 'PipraPay'); |
||||
|
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("No transaction ID found for verification.")); |
||||
|
} |
||||
|
|
||||
|
// Use correct endpoint and method
|
||||
|
$verify_url = $piprapay_config['base_url'] . '/verify-payments'; |
||||
|
|
||||
|
// Use correct field name 'pp_id' instead of 'transaction_id'
|
||||
|
$payload = [ |
||||
|
'pp_id' => $trx['gateway_trx_id'] |
||||
|
]; |
||||
|
|
||||
|
$headers = [ |
||||
|
'accept: application/json', |
||||
|
'content-type: application/json', |
||||
|
'mh-piprapay-api-key: ' . $piprapay_config['api_key'] |
||||
|
]; |
||||
|
|
||||
|
_log("PipraPay Verification Request - PP ID: " . $trx['gateway_trx_id'], 'PipraPay'); |
||||
|
|
||||
|
$response = Http::postJsonData($verify_url, $payload, $headers); |
||||
|
$result = json_decode($response, true); |
||||
|
|
||||
|
_log("PipraPay Verification Raw Response: " . $response, 'PipraPay'); |
||||
|
_log("PipraPay Verification Parsed Response: " . json_encode($result), 'PipraPay'); |
||||
|
|
||||
|
// Check if API call was successful
|
||||
|
if (!$result || !is_array($result)) { |
||||
|
_log("PipraPay Verification - Invalid response format", 'PipraPay'); |
||||
|
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Invalid response from payment gateway.")); |
||||
|
} |
||||
|
|
||||
|
// Check if transaction is already paid
|
||||
|
if ($trx['status'] == 2) { |
||||
|
_log("PipraPay Verification - Transaction already paid", 'PipraPay'); |
||||
|
r2(U . "order/view/" . $trx['id'], 's', Lang::T("Transaction has been paid.")); |
||||
|
} |
||||
|
|
||||
|
// Check for success - PipraPay API might have different response structure
|
||||
|
$is_paid = false; |
||||
|
$payment_status = ''; |
||||
|
$payment_method = ''; |
||||
|
$payment_channel = ''; |
||||
|
|
||||
|
// Check multiple possible response formats from PipraPay
|
||||
|
if (isset($result['status']) && $result['status'] === true) { |
||||
|
// Format 1: Direct status in response
|
||||
|
if (isset($result['payment_status'])) { |
||||
|
$payment_status = strtolower(trim($result['payment_status'])); |
||||
|
$is_paid = in_array($payment_status, ['success', 'completed', 'paid', 'successful', 'processed', 'complete']); |
||||
|
} |
||||
|
// Format 2: Data array with status
|
||||
|
elseif (isset($result['data']['payment_status'])) { |
||||
|
$payment_status = strtolower(trim($result['data']['payment_status'])); |
||||
|
$is_paid = in_array($payment_status, ['success', 'completed', 'paid', 'successful', 'processed', 'complete']); |
||||
|
} |
||||
|
// Format 3: Check if payment is verified directly
|
||||
|
elseif (isset($result['is_paid']) && $result['is_paid'] === true) { |
||||
|
$is_paid = true; |
||||
|
$payment_status = 'paid'; |
||||
|
} |
||||
|
// Format 4: Check payment object
|
||||
|
elseif (isset($result['payment']['status'])) { |
||||
|
$payment_status = strtolower(trim($result['payment']['status'])); |
||||
|
$is_paid = in_array($payment_status, ['success', 'completed', 'paid', 'successful', 'processed', 'complete']); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Extract payment method and channel if available
|
||||
|
if (isset($result['payment_method'])) { |
||||
|
$payment_method = $result['payment_method']; |
||||
|
} |
||||
|
if (isset($result['payment_channel'])) { |
||||
|
$payment_channel = $result['payment_channel']; |
||||
|
} |
||||
|
if (isset($result['data']['payment_method'])) { |
||||
|
$payment_method = $result['data']['payment_method']; |
||||
|
} |
||||
|
if (isset($result['data']['payment_channel'])) { |
||||
|
$payment_channel = $result['data']['payment_channel']; |
||||
|
} |
||||
|
|
||||
|
_log("PipraPay Payment Analysis - Status: " . $payment_status . ", Is Paid: " . ($is_paid ? 'Yes' : 'No'), 'PipraPay'); |
||||
|
|
||||
|
if ($is_paid) { |
||||
|
_log("PipraPay Payment Successful - Activating package", 'PipraPay'); |
||||
|
|
||||
|
// Update payment gateway record
|
||||
|
$pg_trx = ORM::for_table('tbl_payment_gateway') |
||||
|
->where('gateway_trx_id', $trx['gateway_trx_id']) |
||||
|
->find_one(); |
||||
|
|
||||
|
if ($pg_trx) { |
||||
|
$pg_trx->pg_paid_response = json_encode($result); |
||||
|
$pg_trx->payment_method = $payment_method ?: $piprapay_config['gateway_name']; |
||||
|
$pg_trx->payment_channel = $payment_channel ?: $piprapay_config['gateway_name']; |
||||
|
$pg_trx->paid_date = date('Y-m-d H:i:s'); |
||||
|
$pg_trx->status = 2; // Paid
|
||||
|
$pg_trx->trx_invoice = $trx['id']; |
||||
|
$pg_trx->save(); |
||||
|
_log("PipraPay - Updated payment gateway record ID: " . $pg_trx['id'] . " with status 2", 'PipraPay'); |
||||
|
} |
||||
|
|
||||
|
// Activate user package
|
||||
|
if (!Package::rechargeUser($user['id'], $trx['routers'], $trx['plan_id'], $trx['gateway'], $piprapay_config['gateway_name'])) { |
||||
|
_log("PipraPay - Failed to activate package for user: " . $user['id'], 'PipraPay'); |
||||
|
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Failed to activate your Package, try again later.")); |
||||
|
} |
||||
|
|
||||
|
// Update transaction
|
||||
|
$trx->pg_paid_response = json_encode($result); |
||||
|
$trx->payment_method = $payment_method ?: $piprapay_config['gateway_name']; |
||||
|
$trx->payment_channel = $payment_channel ?: $piprapay_config['gateway_name']; |
||||
|
$trx->paid_date = date('Y-m-d H:i:s'); |
||||
|
$trx->status = 2; |
||||
|
$trx->save(); |
||||
|
|
||||
|
_log("PipraPay - Transaction marked as paid: " . $trx['id'], 'PipraPay'); |
||||
|
r2(U . "order/view/" . $trx['id'], 's', Lang::T("Payment successful! Your package has been activated.")); |
||||
|
} else { |
||||
|
_log("PipraPay Payment Not Successful - Status: " . $payment_status, 'PipraPay'); |
||||
|
r2(U . "order/view/" . $trx['id'], 'w', Lang::T("Payment status: ") . $payment_status); |
||||
|
} |
||||
|
} catch (Exception $e) { |
||||
|
_log("PipraPay Verification Exception: " . $e->getMessage(), 'PipraPay'); |
||||
|
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("System error during verification.")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// REQUIRED: This function is called by the callback router
|
||||
|
function piprapay_payment_notification() |
||||
|
{ |
||||
|
global $piprapay_config; |
||||
|
|
||||
|
_log("=== PIPRAPAY PAYMENT NOTIFICATION CALLED ===", 'PipraPay'); |
||||
|
_log("GET Parameters: " . json_encode($_GET), 'PipraPay'); |
||||
|
_log("POST Parameters: " . json_encode($_POST), 'PipraPay'); |
||||
|
_log("Request Method: " . $_SERVER['REQUEST_METHOD'], 'PipraPay'); |
||||
|
_log("Raw Query String: " . ($_SERVER['QUERY_STRING'] ?? 'NONE'), 'PipraPay'); |
||||
|
|
||||
|
// Call the main callback handler
|
||||
|
piprapay_callback_handler(); |
||||
|
} |
||||
|
|
||||
|
// Enhanced callback handler that handles both user redirects and auto-verify
|
||||
|
function piprapay_callback_handler() |
||||
|
{ |
||||
|
global $piprapay_config; |
||||
|
|
||||
|
_log("PipraPay Callback Handler Started", 'PipraPay'); |
||||
|
|
||||
|
try { |
||||
|
// SCENARIO 1: Handle POST requests (Auto-verify/Webhook)
|
||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') { |
||||
|
_log("PipraPay - Processing POST Request", 'PipraPay'); |
||||
|
|
||||
|
// Handle auto-verify requests from system
|
||||
|
if (isset($_POST['action']) && $_POST['action'] === 'auto_verify') { |
||||
|
_log("PipraPay - Auto-verify request detected", 'PipraPay'); |
||||
|
|
||||
|
// Find the most recent unpaid transaction
|
||||
|
$pg_trx = ORM::for_table('tbl_payment_gateway') |
||||
|
->where('status', 1) // Unpaid status
|
||||
|
->where('gateway', 'piprapay') |
||||
|
->order_by_desc('id') |
||||
|
->find_one(); |
||||
|
|
||||
|
if ($pg_trx && !empty($pg_trx['trx_invoice'])) { |
||||
|
$invoice_id = $pg_trx['trx_invoice']; |
||||
|
_log("PipraPay - Found unpaid transaction for auto-verify: " . $invoice_id, 'PipraPay'); |
||||
|
|
||||
|
$trx = ORM::for_table('tbl_transactions')->find_one($invoice_id); |
||||
|
$user = ORM::for_table('tbl_customers')->find_one($pg_trx['user_id']); |
||||
|
|
||||
|
if ($trx && $user) { |
||||
|
_log("PipraPay - Auto-verifying transaction: " . $invoice_id, 'PipraPay'); |
||||
|
piprapay_get_status($trx, $user); |
||||
|
} else { |
||||
|
_log("PipraPay - Transaction or user not found for auto-verify", 'PipraPay'); |
||||
|
} |
||||
|
} else { |
||||
|
_log("PipraPay - No unpaid transactions found for auto-verify", 'PipraPay'); |
||||
|
} |
||||
|
|
||||
|
// Return success for auto-verify
|
||||
|
http_response_code(200); |
||||
|
echo json_encode(['status' => 'processed']); |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
// Handle PipraPay webhook data
|
||||
|
if (!empty($_POST['pp_id']) || !empty($_POST['transaction_id'])) { |
||||
|
$transaction_id = $_POST['pp_id'] ?? $_POST['transaction_id'] ?? ''; |
||||
|
_log("PipraPay - Webhook with transaction ID: " . $transaction_id, 'PipraPay'); |
||||
|
|
||||
|
if (!empty($transaction_id)) { |
||||
|
// Find payment gateway record
|
||||
|
$pg_trx = ORM::for_table('tbl_payment_gateway') |
||||
|
->where('gateway_trx_id', $transaction_id) |
||||
|
->find_one(); |
||||
|
|
||||
|
if ($pg_trx && !empty($pg_trx['trx_invoice'])) { |
||||
|
// Find transaction and user
|
||||
|
$trx = ORM::for_table('tbl_transactions')->find_one($pg_trx['trx_invoice']); |
||||
|
$user = ORM::for_table('tbl_customers')->find_one($pg_trx['user_id']); |
||||
|
|
||||
|
if ($trx && $user) { |
||||
|
_log("PipraPay Webhook - Processing transaction: " . $transaction_id, 'PipraPay'); |
||||
|
piprapay_get_status($trx, $user); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Return success for webhook
|
||||
|
http_response_code(200); |
||||
|
echo json_encode(['status' => 'success']); |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
// Default response for POST requests
|
||||
|
http_response_code(200); |
||||
|
echo json_encode(['status' => 'received']); |
||||
|
exit; |
||||
|
} |
||||
|
|
||||
|
// SCENARIO 2: Handle GET requests (User redirects)
|
||||
|
if ($_SERVER['REQUEST_METHOD'] === 'GET') { |
||||
|
_log("PipraPay - Processing GET Request (User Redirect)", 'PipraPay'); |
||||
|
|
||||
|
// Parse invoice_id from multiple possible sources
|
||||
|
$invoice_id = null; |
||||
|
|
||||
|
// Method 1: Direct GET parameter
|
||||
|
if (isset($_GET['invoice_id'])) { |
||||
|
$invoice_id = intval($_GET['invoice_id']); |
||||
|
_log("PipraPay - Found invoice_id in GET: " . $invoice_id, 'PipraPay'); |
||||
|
} |
||||
|
// Method 2: Parse from query string
|
||||
|
else if (isset($_SERVER['QUERY_STRING'])) { |
||||
|
parse_str($_SERVER['QUERY_STRING'], $query_params); |
||||
|
if (isset($query_params['invoice_id'])) { |
||||
|
$invoice_id = intval($query_params['invoice_id']); |
||||
|
_log("PipraPay - Found invoice_id in query string: " . $invoice_id, 'PipraPay'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($invoice_id) { |
||||
|
_log("PipraPay Callback - Processing Invoice ID: " . $invoice_id, 'PipraPay'); |
||||
|
|
||||
|
// Find the transaction
|
||||
|
$trx = ORM::for_table('tbl_transactions')->find_one($invoice_id); |
||||
|
if (!$trx) { |
||||
|
_log("PipraPay Callback - Transaction not found: " . $invoice_id, 'PipraPay'); |
||||
|
r2(U . 'order/package', 'e', Lang::T("Transaction not found.")); |
||||
|
} |
||||
|
|
||||
|
// Find user
|
||||
|
$user = ORM::for_table('tbl_customers')->find_one($trx['customer_id']); |
||||
|
if (!$user) { |
||||
|
_log("PipraPay Callback - User not found for transaction: " . $invoice_id, 'PipraPay'); |
||||
|
r2(U . 'order/package', 'e', Lang::T("User not found.")); |
||||
|
} |
||||
|
|
||||
|
// If we don't have gateway_trx_id, try to find it from payment_gateway table
|
||||
|
if (empty($trx['gateway_trx_id'])) { |
||||
|
$pg_trx = ORM::for_table('tbl_payment_gateway') |
||||
|
->where('username', $user['username']) |
||||
|
->where('status', 1) // Unpaid status
|
||||
|
->order_by_desc('id') |
||||
|
->find_one(); |
||||
|
|
||||
|
if ($pg_trx && !empty($pg_trx['gateway_trx_id'])) { |
||||
|
$trx->gateway_trx_id = $pg_trx['gateway_trx_id']; |
||||
|
$trx->save(); |
||||
|
_log("PipraPay Callback - Updated transaction with gateway_trx_id: " . $pg_trx['gateway_trx_id'], 'PipraPay'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Verify payment status via API
|
||||
|
piprapay_get_status($trx, $user); |
||||
|
} |
||||
|
|
||||
|
// Handle cancelled payment
|
||||
|
if (isset($_GET['status']) && $_GET['status'] == 'cancel') { |
||||
|
r2(U . 'order/package', 'w', Lang::T("Payment was cancelled. Please try again.")); |
||||
|
} |
||||
|
|
||||
|
// Default redirect if no invoice_id found
|
||||
|
_log("PipraPay Callback - No invoice_id found in GET request", 'PipraPay'); |
||||
|
r2(U . 'order/package', 'e', Lang::T("Payment verification failed - no transaction ID found.")); |
||||
|
} |
||||
|
|
||||
|
} catch (Exception $e) { |
||||
|
_log("PipraPay Callback Exception: " . $e->getMessage(), 'PipraPay'); |
||||
|
r2(U . 'order/package', 'e', Lang::T("System error occurred.")); |
||||
|
} |
||||
} |
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue