Browse Source

Update 'pipprapay.php'

master
alamin 5 months ago
parent
commit
f6346bf43a
  1. 371
      pipprapay.php

371
pipprapay.php

@ -3,279 +3,244 @@
/**
* PHP Mikrotik Billing (https://github.com/hotspotbilling/phpnuxbill/)
*
* Payment Gateway PippraPay (https://piprapay.readme.io/)
* Payment Gateway PipraPay
* Single File Plugin with Direct Configuration
**/
function pipprapay_validate_config()
{
global $config;
if (empty($config['pipprapay_api_key'])) {
sendTelegram("PippraPay payment gateway not configured");
r2(U . 'order/package', 'w', Lang::T("Admin has not yet setup PippraPay payment gateway, please tell admin"));
}
}
// PipraPay Configuration
$piprapay_config = [
'api_key' => '186691761268d6f85579c84532234998155044887968d6f85579c891167595247',
'base_url' => 'https://pay.wifibills.com/api',
'gateway_name' => 'PipraPay'
];
function pipprapay_show_config()
function piprapay_validate_config()
{
global $ui, $config;
$ui->assign('_title', 'PippraPay - Payment Gateway');
$ui->display('pipprapay.tpl');
global $piprapay_config;
}
function pipprapay_save_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="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;
$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();
_log('[' . $admin['username'] . ']: ' . Lang::T('PipraPay_Configuration_Viewed'), 'Admin', $admin['id']);
r2(U . 'paymentgateway/piprapay', 's', Lang::T('PipraPay_is_preconfigured'));
}
// 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)
function piprapay_create_transaction($trx, $user)
{
global $config;
global $piprapay_config;
pipprapay_validate_config();
$success_url = U . 'callback/piprapay?status=success&invoice_id=' . $trx['id'];
$cancel_url = U . 'order/view/' . $trx['id'];
$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' => [
// Create simple metadata
$metadata = [
'invoice_id' => $trx['id'],
'customer_id' => $user['id'],
'customer_username' => $user['username'],
'system' => 'NuxBill'
]
'customer_name' => $user['fullname'] ?: $user['username'],
'plan_id' => $trx['plan_id']
];
$result = pipprapay_api_call('/create-charge', $payload);
// 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
];
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']));
}
$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';
$paymentData = $result['data'];
// Make the API call
$result = json_decode(Http::postJsonData($create_charge_url, $payload, $headers), true);
if ($paymentData['status'] === 'success' && !empty($paymentData['data']['checkout_url'])) {
// 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();
$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);
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();
header('Location: ' . $paymentData['data']['checkout_url']);
// Redirect to payment gateway
header('Location: ' . $result['pp_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')));
$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 pipprapay_get_status($trx, $user)
function piprapay_get_status($trx, $user)
{
global $config;
global $piprapay_config;
if (empty($trx['gateway_trx_id'])) {
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Transaction ID not found"));
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("No transaction ID found for verification."));
}
$result = pipprapay_api_call('/verify-payments', ['transaction_id' => $trx['gateway_trx_id']]);
$verify_url = $piprapay_config['base_url'] . '/verify-payments';
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']));
}
$payload = [
'transaction_id' => $trx['gateway_trx_id']
];
$verificationData = $result['data'];
$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."));
}
// 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')) {
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($verificationData);
$trx->payment_method = 'PippraPay';
$trx->payment_channel = 'PippraPay';
$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("Transaction has been paid."));
} elseif ($paymentStatus == 'failed' || $paymentStatus == 'cancelled') {
r2(U . "order/view/" . $trx['id'], 'e', Lang::T("Payment failed or was cancelled."));
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("Transaction still pending."));
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."));
}
// 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');
// 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_payment_gateway')
->where('gateway_trx_id', $transactionId)
->find_one();
$trx = ORM::for_table('tbl_transactions')->find_one($invoice_id);
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);
}
}
r2(U . 'order/package', 'e', Lang::T("Transaction not found."));
}
http_response_code(200);
echo 'OK';
// 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."));
}
function pipprapay_api_call($endpoint, $payload)
{
global $config;
$baseUrl = $config['pipprapay_base_url'] ?? 'https://pay.wifibills.com/api';
$url = rtrim($baseUrl, '/') . $endpoint;
// 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();
$headers = [
'Authorization: Bearer ' . $config['pipprapay_api_key'],
'Content-Type: application/json',
'Accept: application/json'
];
if ($pg_trx) {
// Update transaction with gateway_trx_id
$trx->gateway_trx_id = $pg_trx['gateway_trx_id'];
$trx->save();
$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
];
// 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."));
}
$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'
];
// Handle cancelled payment
if (isset($_GET['status']) && $_GET['status'] == 'cancel') {
r2(U . 'order/package', 'w', Lang::T("Payment was cancelled. Please try again."));
}
return [
'success' => true,
'data' => $decodedResponse
];
// Default redirect
r2(U . 'order/package');
}
function pipprapay_get_server()
{
global $config;
return $config['pipprapay_base_url'] ?? 'https://pay.wifibills.com/api';
// Register callback route
if (defined('CALLBACK_ROUTE')) {
piprapay_callback_handler();
}
?>
Loading…
Cancel
Save