diff --git a/pipprapay.php b/pipprapay.php index 7570ecf..92e3e2f 100644 --- a/pipprapay.php +++ b/pipprapay.php @@ -1,281 +1,246 @@ -assign('_title', 'PippraPay - Payment Gateway'); - $ui->display('pipprapay.tpl'); -} - -function pipprapay_save_config() -{ - global $admin; - $pipprapay_api_key = _post('pipprapay_api_key'); - $pipprapay_base_url = _post('pipprapay_base_url'); - - // Save API Key - $d = ORM::for_table('tbl_appconfig')->where('setting', 'pipprapay_api_key')->find_one(); - if ($d) { - $d->value = $pipprapay_api_key; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'pipprapay_api_key'; - $d->value = $pipprapay_api_key; - $d->save(); - } - - // Save Base URL - $d = ORM::for_table('tbl_appconfig')->where('setting', 'pipprapay_base_url')->find_one(); - if ($d) { - $d->value = $pipprapay_base_url; - $d->save(); - } else { - $d = ORM::for_table('tbl_appconfig')->create(); - $d->setting = 'pipprapay_base_url'; - $d->value = $pipprapay_base_url; - $d->save(); - } - - _log('[' . $admin['username'] . ']: PippraPay ' . Lang::T('Settings_Saved_Successfully'), 'Admin', $admin['id']); - r2(U . 'paymentgateway/pipprapay', 's', Lang::T('Settings_Saved_Successfully')); -} - -function pipprapay_create_transaction($trx, $user) -{ - global $config; - - pipprapay_validate_config(); - - $callbackUrl = U . 'callback/pipprapay'; - $redirectUrl = U . 'order/view/' . $trx['id'] . '/check'; - - $payload = [ - 'amount' => $trx['price'] * 100, // Convert to kobo (assuming price is in main currency unit) - 'currency' => 'NGN', - 'email' => $user['email'], - 'invoice_id' => $trx['id'], - 'description' => 'Payment for invoice #' . $trx['id'], - 'callback_url' => $callbackUrl, - 'redirect_url' => $redirectUrl, - 'metadata' => [ - 'invoice_id' => $trx['id'], - 'customer_id' => $user['id'], - 'customer_username' => $user['username'], - 'system' => 'NuxBill' - ] - ]; - - $result = pipprapay_api_call('/create-charge', $payload); - - if (!$result['success']) { - sendTelegram("PippraPay payment failed\n\n" . json_encode($result, JSON_PRETTY_PRINT)); - r2(U . 'order/package', 'e', Lang::T("Failed to create transaction. " . $result['error'])); - } - - $paymentData = $result['data']; - - if ($paymentData['status'] === 'success' && !empty($paymentData['data']['checkout_url'])) { - $d = ORM::for_table('tbl_payment_gateway') - ->where('username', $user['username']) - ->where('status', 1) - ->find_one(); - $d->gateway_trx_id = $paymentData['data']['transaction_id'] ?? $paymentData['data']['reference']; - $d->pg_url_payment = $paymentData['data']['checkout_url']; - $d->pg_request = json_encode($paymentData); - $d->expired_date = date('Y-m-d H:i:s', strtotime('+ 24 HOURS')); - $d->save(); - - header('Location: ' . $paymentData['data']['checkout_url']); - exit(); - } else { - sendTelegram("PippraPay payment creation failed\n\n" . json_encode($paymentData, JSON_PRETTY_PRINT)); - r2(U . 'order/package', 'e', Lang::T("Failed to create payment: " . ($paymentData['message'] ?? 'Unknown error'))); - } -} - -function pipprapay_get_status($trx, $user) -{ - global $config; - - if (empty($trx['gateway_trx_id'])) { - r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Transaction ID not found")); - } - - $result = pipprapay_api_call('/verify-payments', ['transaction_id' => $trx['gateway_trx_id']]); - - if (!$result['success']) { - sendTelegram("PippraPay payment verification failed\n\n" . json_encode($result, JSON_PRETTY_PRINT)); - r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Failed to verify transaction. " . $result['error'])); - } - - $verificationData = $result['data']; - - if ($trx['status'] == 2) { - r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Transaction has been paid.")); - } - - // Check payment status based on PippraPay response structure - $paymentStatus = strtolower($verificationData['data']['status'] ?? 'pending'); - - if ($paymentStatus == 'success' || $paymentStatus == 'completed') { - if (!Package::rechargeUser($user['id'], $trx['routers'], $trx['plan_id'], $trx['gateway'], 'PippraPay')) { - r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Failed to activate your Package, try again later.")); - } - - $trx->pg_paid_response = json_encode($verificationData); - $trx->payment_method = 'PippraPay'; - $trx->payment_channel = 'PippraPay'; - $trx->paid_date = date('Y-m-d H:i:s'); - $trx->status = 2; - $trx->save(); - - r2(U . "order/view/" . $trx['id'], 's', Lang::T("Transaction has been paid.")); - } elseif ($paymentStatus == 'failed' || $paymentStatus == 'cancelled') { - r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Payment failed or was cancelled.")); - } else { - r2(U . "order/view/" . $trx['id'], 'w', Lang::T("Transaction still pending.")); - } -} - -// Callback handler -function pipprapay_payment_notification() -{ - $input = file_get_contents('php://input'); - $data = json_decode($input, true); - - if (empty($data) || !isset($data['transaction_id'])) { - http_response_code(400); - die('Invalid IPN data'); - } - - $transactionId = $data['transaction_id']; - $status = strtolower($data['status'] ?? 'pending'); - $invoiceId = $data['invoice_id'] ?? ''; - $amount = $data['amount'] ?? 0; - - // Verify the payment - $result = pipprapay_api_call('/verify-payments', ['transaction_id' => $transactionId]); - - if (!$result['success']) { - http_response_code(400); - die('Verification failed: ' . $result['error']); - } - - $verificationData = $result['data']; - $verifiedStatus = strtolower($verificationData['data']['status'] ?? 'pending'); - - // Find the transaction - $trx = ORM::for_table('tbl_payment_gateway') - ->where('gateway_trx_id', $transactionId) - ->find_one(); - - if (!$trx) { - http_response_code(404); - die('Transaction not found'); - } - - // Update transaction based on status - if ($verifiedStatus == 'success' || $verifiedStatus == 'completed') { - $user = ORM::for_table('tbl_customers')->where('username', $trx['username'])->find_one(); - - if ($user && $trx['status'] != 2) { - if (Package::rechargeUser($user['id'], $trx['routers'], $trx['plan_id'], $trx['gateway'], 'PippraPay')) { - $trx->pg_paid_response = json_encode($verificationData); - $trx->payment_method = 'PippraPay'; - $trx->payment_channel = 'PippraPay'; - $trx->paid_date = date('Y-m-d H:i:s'); - $trx->status = 2; - $trx->save(); - - sendTelegram("PippraPay payment successful for invoice: " . $invoiceId); - } - } - } - - http_response_code(200); - echo 'OK'; -} - -function pipprapay_api_call($endpoint, $payload) -{ - global $config; - - $baseUrl = $config['pipprapay_base_url'] ?? 'https://pay.wifibills.com/api'; - $url = rtrim($baseUrl, '/') . $endpoint; - - $headers = [ - 'Authorization: Bearer ' . $config['pipprapay_api_key'], - 'Content-Type: application/json', - 'Accept: application/json' - ]; - - $ch = curl_init(); - - curl_setopt_array($ch, [ - CURLOPT_URL => $url, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_POST => true, - CURLOPT_POSTFIELDS => json_encode($payload), - CURLOPT_HTTPHEADER => $headers, - CURLOPT_TIMEOUT => 30, - CURLOPT_SSL_VERIFYPEER => true, - CURLOPT_USERAGENT => 'NuxBill-PippraPay/1.0' - ]); - - $response = curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = curl_error($ch); - curl_close($ch); - - if ($error) { - return [ - 'success' => false, - 'error' => 'cURL Error: ' . $error - ]; - } - - $decodedResponse = json_decode($response, true); - - if ($httpCode !== 200) { - return [ - 'success' => false, - 'error' => 'HTTP Error: ' . $httpCode, - 'response' => $decodedResponse - ]; - } - - if (json_last_error() !== JSON_ERROR_NONE) { - return [ - 'success' => false, - 'error' => 'Invalid JSON response' - ]; - } - - return [ - 'success' => true, - 'data' => $decodedResponse - ]; -} - -function pipprapay_get_server() -{ - global $config; - return $config['pipprapay_base_url'] ?? 'https://pay.wifibills.com/api'; -} -?> \ No newline at end of file + '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 ' +
+
+
+
' . $piprapay_config['gateway_name'] . ' Configuration
+
+
+

' . $piprapay_config['gateway_name'] . ' Gateway

+

This payment gateway is pre-configured and ready to use.

+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ Gateway Active
+ ' . $piprapay_config['gateway_name'] . ' is ready to accept payments. +
+
+
+
+
'; +} + +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; + + $success_url = U . 'callback/piprapay?status=success&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'; + + // Make the API call + $result = json_decode(Http::postJsonData($create_charge_url, $payload, $headers), true); + + // 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->created_date = date('Y-m-d H:i:s'); + } + $d->gateway_trx_id = $transaction_id; + $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->save(); + + // Redirect to payment gateway + header('Location: ' . $result['pp_url']); + exit(); + } else { + $error_message = 'Payment URL not received from gateway'; + r2(U . 'order/package', 'e', Lang::T("Failed to create transaction. ") . $error_message); + } + } else { + $error_message = $result['message'] ?? 'Failed to create payment'; + r2(U . 'order/package', 'e', Lang::T("Failed to create transaction. ") . $error_message); + } +} + +function piprapay_get_status($trx, $user) +{ + global $piprapay_config; + + if (empty($trx['gateway_trx_id'])) { + r2(U . "order/view/" . $trx['id'], 'e', Lang::T("No transaction ID found for verification.")); + } + + $verify_url = $piprapay_config['base_url'] . '/verify-payments'; + + $payload = [ + 'transaction_id' => $trx['gateway_trx_id'] + ]; + + $headers = [ + 'accept: application/json', + 'content-type: application/json', + 'mh-piprapay-api-key: ' . $piprapay_config['api_key'] + ]; + + $result = json_decode(Http::postJsonData($verify_url, $payload, $headers), true); + + // Check for success using the correct response format + if (isset($result['status']) && $result['status'] === true && isset($result['payment_status'])) { + $payment_status = strtolower($result['payment_status']); + + if ($payment_status == 'success' || $payment_status == 'completed' || $payment_status == 'paid') { + if ($trx['status'] == 2) { + r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Transaction has been paid.")); + } + + if (!Package::rechargeUser($user['id'], $trx['routers'], $trx['plan_id'], $trx['gateway'], $piprapay_config['gateway_name'])) { + r2(U . "order/view/" . $trx['id'], 'd', Lang::T("Failed to activate your Package, try again later.")); + } + + $trx->pg_paid_response = json_encode($result); + $trx->payment_method = $piprapay_config['gateway_name']; + $trx->payment_channel = $piprapay_config['gateway_name']; + $trx->paid_date = date('Y-m-d H:i:s'); + $trx->status = 2; + $trx->save(); + + r2(U . "order/view/" . $trx['id'], 's', Lang::T("Payment successful! Your package has been activated.")); + } else { + r2(U . "order/view/" . $trx['id'], 'w', Lang::T("Payment status: ") . $result['payment_status']); + } + } else { + $error_message = $result['message'] ?? 'Verification failed'; + r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Failed to verify payment. Please try again later.")); + } +} + +// Simple callback handler +function piprapay_callback_handler() +{ + // Handle successful payment redirect + if (isset($_GET['status']) && $_GET['status'] == 'success' && isset($_GET['invoice_id'])) { + $invoice_id = $_GET['invoice_id']; + + // Find the transaction + $trx = ORM::for_table('tbl_transactions')->find_one($invoice_id); + if (!$trx) { + 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) { + r2(U . 'order/package', 'e', Lang::T("User not found.")); + } + + // Find payment gateway transaction + $pg_trx = ORM::for_table('tbl_payment_gateway') + ->where('username', $user['username']) + ->where('status', 1) + ->order_by_desc('id') + ->find_one(); + + if ($pg_trx) { + // Update transaction with gateway_trx_id + $trx->gateway_trx_id = $pg_trx['gateway_trx_id']; + $trx->save(); + + // Verify payment status via API + piprapay_get_status($trx, $user); + } else { + r2(U . 'order/package', 'w', Lang::T("Payment verification in progress. Please check your order status in a few moments.")); + } + } + + // 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 + r2(U . 'order/package'); +} + +// Register callback route +if (defined('CALLBACK_ROUTE')) { + piprapay_callback_handler(); +} \ No newline at end of file