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'; } ?>