midtrans pay, but not yet validated

This commit is contained in:
Ibnu Maksum 2022-09-09 16:46:39 +07:00
parent e9d67ce220
commit dd46273a04
No known key found for this signature in database
GPG Key ID: 7FC82848810579E5
10 changed files with 195 additions and 86 deletions

View File

@ -1,47 +1,39 @@
# PHP Mikrotik Billing # PHP Mikrotik Billing
----
![N|phpmixbill](http://4.bp.blogspot.com/-3OWL5OI7pqU/VjocUDdzMDI/AAAAAAAAAiA/s_XJN0_mDlk/s640/Screenshot_8.png) ## Feature
----
This project maintained by [@ibnux](https://twitter.com/ibnux)
Aplikasi ini dikelola oleh [@ibnux](https://twitter.com/ibnux)
----
Download [Mikrotik Login Template](https://github.com/ibnux/phpmixbill-mikrotik-login-template)
Features:
----
- Voucher Generator and Print - Voucher Generator and Print
- Self registration, user must have voucher before registration - Self registration, user must have voucher before registration
- Multi Router Mikrotik - Multi Router Mikrotik
- Hotspot & PPPOE - Hotspot & PPPOE
- Easy Installation - Easy Installation
- Multi Language - Multi Language
- RADIUS
- Payment Gateway Midtrans, Xendit and Tripay
- SMS validation for login
- Whatsapp Notification to Consumer
- Telegram Notification for Admin
TODOS: ## Installation
----
- SMS Notification to user - Rename **pages_template** to **pages
- send receipt via SMS or EMAIL - make writeable **system** folder or create file **system/config.php** and make it writeable
- Social Media Login - make writeable folder **ui/cache/** and **ui/compiled**
- Open webs and run installation
- set cronjobs or scheduller for **system/cron.php**
Radius system need to set radius to use **system/radius.php** you can ask me for paid support.
Installation
----
See [WIKI](https://github.com/ibnux/phpmixbill/wiki/Instalation) See [WIKI](https://github.com/ibnux/phpmixbill/wiki/Instalation)
baca [WIKI](https://github.com/ibnux/phpmixbill/wiki/Instalation) baca [WIKI](https://github.com/ibnux/phpmixbill/wiki/Instalation)
System Requirements ## System Requirements
----
Most current web servers with PHP & MySQL installed will be capable of running PHPMixBill Most current web servers with PHP & MySQL installed will be capable of running PHPMixBill
Minimum Requirements Minimum Requirements
- Linux or Windows OS - Linux or Windows OS
- PHP Version 5.3+ - PHP Version 5.3+
- Both PDO & MySQLi Support - Both PDO & MySQLi Support
@ -51,33 +43,24 @@ Minimum Requirements
can be Installed in Raspberry Pi Device. can be Installed in Raspberry Pi Device.
The problem with windows is hard to set cronjob, better Linux The problem with windows is hard to set cronjob, better Linux
JASA
----
Terima jasa instalasi PHPMIXBILL beserta mikrotiknya. ## Paid Support
Via Team Viewer maupun Barang dibeli dari saya dan tinggal pakai. Start from Rp 500.000 or $50
1. Unit Mikrotik Router [Telegram](https://t.me/ibnux)
2. Raspberry Pi Server (RasPi + Casing + Memory 4GB + Adaptor)
Jasa kurang lebih Rp. 500.000, belum termasuk ongkir dan harga perangkat, Gratis Tanya Jawab via Messenger (Jika lagi senggang). [Website](https://ibnux.net/layanan)
hubungi ibnux di [Twitter](https://twitter.com/ibnux) atau di [facebook](https://facebook.com/ibnumaksum) ## License
License
----
GNU General Public License version 2 or later GNU General Public License version 2 or later
see LICENSE file see LICENSE file
## Donate to ibnux
Donate to ibnux [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/ibnux)
----
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6RBNGRJMZVV7C)
BCA: 5410454825 BCA: 5410454825

View File

@ -78,6 +78,66 @@ function xendit_get_invoice($xendittrxID){
*/ */
} }
/** MIDTRANS */
function midtrans_create_payment($trxID, $amount){
global $midtrans_server,$_c;
$json = [
'transaction_details ' => [
'order_id' => $trxID,
'gross_amount' => $amount,
"payment_link_id" => alphanumeric(ucwords($_c['CompanyName']))."_".crc32($_c['CompanyName'])."_".$trxID
],
'enabled_payments' => explode(',',$_c['midtrans_channel']),
"usage_limit"=> 1,
"expiry" => [
"duration" => 24,
"unit" => "hour"
]
];
$json = json_decode(postJsonData($midtrans_server.'v1/payment-links', $json, ['Authorization: Basic '.base64_encode($_c['midtrans_server_key'].':')]),true);
if(!empty($json['error_messages'])){
sendTelegram(json_encode("Midtrans create Payment error:\n".alphanumeric($_c['CompanyName'])."_".crc32($_c['CompanyName'])."_".$trxID."\n".$json['error_messages']));
}
return $json;
/*
{
"order_id": "concert-ticket-05", //traxid
"payment_url": "https://app.sandbox.midtrans.com/payment-links/amazing-ticket-payment-123"
}
*/
}
function midtrans_check_payment($midtranstrxID){
global $midtrans_server,$_c;
return json_decode(getData($midtrans_server.'v2/'.$midtranstrxID.'/status', [
'Authorization: Basic '.base64_encode($_c['midtrans_server_key'].':')
]),true);
/*
{
"masked_card": "41111111-1111",
"approval_code": "1599493766402",
"bank": "bni",
"channel_response_code": "00",
"channel_response_message": "Approved",
"transaction_time": "2020-09-07 22:49:26",
"gross_amount": "10000.00",
"currency": "IDR",
"order_id": "SANDBOX-G710367688-806",
"payment_type": "credit_card",
"signature_key": "4d4abc70f5a88b09f48f3ab5cb91245feb0b3d89181117a677767b42f8cbe477f5a0d38af078487071311f97da646c1eb9542c1bbf0b19fa9f12e64605ac405e",
"status_code": "200",
"transaction_id": "3853c491-ca9b-4bcc-ac20-3512ff72a5d0",
"transaction_status": "cancel",
"fraud_status": "challenge",
"status_message": "Success, transaction is found",
"merchant_id": "G710367688",
"card_type": "credit"
}
*/
}
function getData($url, $headers) function getData($url, $headers)
{ {
$ch = curl_init(); $ch = curl_init();

View File

@ -91,29 +91,32 @@ switch ($action) {
$ui->assign('_title', 'TRX #' . $trxid . ' - ' . $config['CompanyName']); $ui->assign('_title', 'TRX #' . $trxid . ' - ' . $config['CompanyName']);
$ui->display('user-orderView.tpl'); $ui->display('user-orderView.tpl');
break; break;
case 'ppoe-buy':
case 'hotspot-buy': case 'hotspot-buy':
if (empty($_c['xendit_secret_key'])) { $back = "order/".str_replace('-buy','',$action);
r2(U . "order/hotspot", 'e', Lang::T("Admin has not yet setup Xendit payment gateway, please tell admin"));
}
$router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2'] * 1); $router = ORM::for_table('tbl_routers')->where('enabled', '1')->find_one($routes['2'] * 1);
$plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3'] * 1); $plan = ORM::for_table('tbl_plans')->where('enabled', '1')->find_one($routes['3'] * 1);
if (empty($router) || empty($plan)) { if (empty($router) || empty($plan)) {
r2(U . "order/hotspot", 'e', Lang::T("Plan Not found")); r2(U . $back, 'e', Lang::T("Plan Not found"));
} }
if ($_c['payment_gateway'] == 'xendit') {
$d = ORM::for_table('tbl_payment_gateway') $d = ORM::for_table('tbl_payment_gateway')
->where('username', $user['username']) ->where('username', $user['username'])
->where('status', 1) ->where('status', 1)
->find_one(); ->find_one();
if ($d) {
if ($d['pg_url_payment']) { if ($d['pg_url_payment']) {
r2(U . "order/view/" . $d['id'], 'w', Lang::T("You already have unpaid transaction, cancel it or pay it.")); r2(U . "order/view/" . $d['id'], 'w', Lang::T("You already have unpaid transaction, cancel it or pay it."));
} }else{
if($_c['payment_gateway']==$d['gateway']){
$id = $d['id']; $id = $d['id'];
}else{ }else{
$d->status = 4;
$d->save();
}
}
if(empty($id)){
$d = ORM::for_table('tbl_payment_gateway')->create(); $d = ORM::for_table('tbl_payment_gateway')->create();
$d->username = $user['username']; $d->username = $user['username'];
$d->gateway = 'xendit'; $d->gateway = $_c['payment_gateway'];
$d->plan_id = $plan['id']; $d->plan_id = $plan['id'];
$d->plan_name = $plan['name_plan']; $d->plan_name = $plan['name_plan'];
$d->routers_id = $router['id']; $d->routers_id = $router['id'];
@ -124,10 +127,15 @@ switch ($action) {
$d->save(); $d->save();
$id = $d->id(); $id = $d->id();
} }
if ($_c['payment_gateway'] == 'xendit') {
if (empty($_c['xendit_secret_key'])) {
sendTelegram("Xendit payment gateway not configured");
r2(U . $back, 'e', Lang::T("Admin has not yet setup Xendit payment gateway, please tell admin"));
}
if ($id) { if ($id) {
$result = xendit_create_invoice($id, $plan['price'], $user['username'], $plan['name_plan']); $result = xendit_create_invoice($id, $plan['price'], $user['username'], $plan['name_plan']);
if (!$result['id']) { if (!$result['id']) {
r2(U . "order/hotspot", 'e', Lang::T("Failed to create transaction.")); r2(U . $back, 'e', Lang::T("Failed to create transaction."));
} }
$d = ORM::for_table('tbl_payment_gateway') $d = ORM::for_table('tbl_payment_gateway')
->where('username', $user['username']) ->where('username', $user['username'])
@ -144,7 +152,34 @@ switch ($action) {
r2(U . "order/view/" . $d['id'], 'w', Lang::T("Failed to create Transaction..")); r2(U . "order/view/" . $d['id'], 'w', Lang::T("Failed to create Transaction.."));
} }
} else if ($_c['payment_gateway'] == 'midtrans') { } else if ($_c['payment_gateway'] == 'midtrans') {
if (empty($_c['midtrans_server_key'])) {
sendTelegram("Midtrans payment gateway not configured");
r2(U . $back, 'e', Lang::T("Admin has not yet setup Midtrans payment gateway, please tell admin"));
}
if ($id) {
$result = midtrans_create_payment($id, $plan['price']);
if (!$result['payment_url']) {
r2(U . $back, 'e', Lang::T("Failed to create transaction."));
}
$d = ORM::for_table('tbl_payment_gateway')
->where('username', $user['username'])
->where('status', 1)
->find_one();
$d->gateway_trx_id = $result['order_id'];
$d->pg_url_payment = $result['payment_url'];
$d->pg_request = json_encode($result);
$d->expired_date = date('Y-m-d H:i:s', strtotime("+1 days"));
$d->save();
r2(U . "order/view/" . $id, 'w', Lang::T("Create Transaction Success"));
exit();
} else {
r2(U . "order/view/" . $d['id'], 'w', Lang::T("Failed to create Transaction.."));
}
} else if ($_c['payment_gateway'] == 'tripay') { } else if ($_c['payment_gateway'] == 'tripay') {
if (empty($_c['tripay_secret_key'])) {
sendTelegram("Tripay payment gateway not configured");
r2(U . $back, 'e', Lang::T("Admin has not yet setup Tripay payment gateway, please tell admin"));
}
} }
break; break;
default: default:

View File

@ -272,3 +272,5 @@ $_L['Transaction_still_unpaid'] = 'Transaction still unpaid.';
$_L['Paid_Date'] = 'Paid Date'; $_L['Paid_Date'] = 'Paid Date';
$_L['Transaction_has_been_paid'] = 'Transaction has been paid.'; $_L['Transaction_has_been_paid'] = 'Transaction has been paid.';
$_L['PAID'] = 'PAID'; $_L['PAID'] = 'PAID';
$_L['Buy_Hotspot_Plan'] = 'Buy Hotspot Plan';
$_L['Buy_PPOE_Plan'] = 'Buy PPOE Plan';

View File

@ -30,6 +30,7 @@
<div class="col-md-6"> <div class="col-md-6">
<input type="text" readonly class="form-control" onclick="this.select()" value="{$_url}callback/midtrans"> <input type="text" readonly class="form-control" onclick="this.select()" value="{$_url}callback/midtrans">
<p class="help-block">{Lang::T('Payment Notification URL, Recurring Notification URL, Pay Account Notification URL')}</p> <p class="help-block">{Lang::T('Payment Notification URL, Recurring Notification URL, Pay Account Notification URL')}</p>
<p class="help-block">Midtrans wajib pake URL Notification</p>
<a href="https://dashboard.midtrans.com/settings/vtweb_configuration" target="_blank" class="help-block">https://dashboard.midtrans.com/settings/vtweb_configuration</a> <a href="https://dashboard.midtrans.com/settings/vtweb_configuration" target="_blank" class="help-block">https://dashboard.midtrans.com/settings/vtweb_configuration</a>
</div> </div>
</div> </div>

View File

@ -21,6 +21,7 @@
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label> <label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
<div class="col-md-6"> <div class="col-md-6">
<input type="text" class="form-control" id="name_plan" maxlength="40" name="name_plan"> <input type="text" class="form-control" id="name_plan" maxlength="40" name="name_plan">
<p class="help-block">{Lang::T('Cannot be change after saved')}</p>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -63,6 +64,7 @@
<option value="{$rs['name']}">{$rs['name']}</option> <option value="{$rs['name']}">{$rs['name']}</option>
{/foreach} {/foreach}
</select> </select>
<p class="help-block">{Lang::T('Cannot be change after saved')}</p>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -137,7 +137,7 @@
</a> </a>
<ul class="inner-drop list-unstyled"> <ul class="inner-drop list-unstyled">
<li {if $_system_menu eq 'order'}class="active"{/if}><a href="{$_url}order/voucher">Voucher</a></li> <li {if $_system_menu eq 'order'}class="active"{/if}><a href="{$_url}order/voucher">Voucher</a></li>
{if $_c['payment_gateway'] != 'none'} {if $_c['payment_gateway'] != 'none' or $_c['payment_gateway'] == '' }
<li {if $_system_menu eq 'order'}class="active"{/if}><a href="{$_url}order/hotspot">Hotspot</a></li> <li {if $_system_menu eq 'order'}class="active"{/if}><a href="{$_url}order/hotspot">Hotspot</a></li>
<li {if $_system_menu eq 'order'}class="active"{/if}><a href="{$_url}order/ppoe">PPOE</a></li> <li {if $_system_menu eq 'order'}class="active"{/if}><a href="{$_url}order/ppoe">PPOE</a></li>
{/if} {/if}

View File

@ -45,6 +45,14 @@
<div class="panel-footer"> <div class="panel-footer">
<a class="btn btn-info btn-block btn-sm waves-effect waves-light" href="{$_url}order/voucher"><i class="ion ion-ios-cart"></i> {$_L['Order_Voucher']}</a> <a class="btn btn-info btn-block btn-sm waves-effect waves-light" href="{$_url}order/voucher"><i class="ion ion-ios-cart"></i> {$_L['Order_Voucher']}</a>
</div> </div>
{if $_c['payment_gateway'] != 'none' or $_c['payment_gateway'] == '' }
<div class="panel-footer">
<div class="btn-group btn-group-justified">
<a href="{$_url}order/hotspot" class="btn btn-primary"><i class="ion ion-ios-cart"></i> {Lang::T('Buy Hotspot Plan')}</a>
<a href="{$_url}order/ppoe" class="btn btn-success"><i class="ion ion-ios-cart"></i> {Lang::T('Buy PPOE Plan')}</a>
</div>
</div>
{/if}
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">

View File

@ -1,28 +1,46 @@
{include file="sections/user-header.tpl"} {include file="sections/user-header.tpl"}
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="panel mb20 panel-primary panel-hovered"> <div class="panel mb20 panel-default panel-hovered">
<div class="panel-heading">Order PPOE</div> <div class="panel-heading">Order PPOE</div>
</div> </div>
{foreach $routers as $router} {foreach $routers as $router}
<div class="panel mb20 panel-info panel-hovered"> <div class="panel mb20 panel-info panel-hovered">
<div class="panel-heading">{$router['name']}</div> <div class="panel-heading">{$router['name']}</div>
{if $router['description'] != ''}
<div class="panel-body"> <div class="panel-body">
{$router['description']} {$router['description']}
</div> </div>
</div> {/if}
<div class="row">
<div class="panel-body row">
{foreach $plans as $plan}
{if $router['name'] eq $plan['routers']}
<div class="col-sm-3"> <div class="col-sm-3">
<div class="panel mb10 panel-default panel-hovered"> <div class="panel mb10 panel-default panel-hovered">
<div class="panel-heading">Router Name</div> <div class="panel-heading"> {$plan['name_plan']}</div>
<div class="panel-body"> <div class="table-responsive">
Router Description <table class="table table-bordered table-striped">
<tbody>
<tr>
<td>Price</td>
<td>{$plan['price']}</td>
</tr>
<tr>
<td>Validity</td>
<td>{$plan['validity']} {$plan['validity_unit']}</td>
</tr>
</tbody>
</table>
</div> </div>
<div class="panel-footer"> <div class="panel-footer">
<a href="" class="btn btn-sm btn-block btn-primary">Buy</a> <a href="{$_url}order/hotspot-buy/{$router['id']}/{$plan['id']}" onclick="return confirm('{Lang::T('Buy this? your active package will be overwrite')}')" class="btn btn-sm btn-block btn-primary">Buy</a>
</div> </div>
</div> </div>
</div> </div>
{/if}
{/foreach}
</div>
</div> </div>
{/foreach} {/foreach}
</div> </div>

View File

@ -75,7 +75,7 @@
{if $trx['status']==1} {if $trx['status']==1}
<div class="panel-footer "> <div class="panel-footer ">
<div class="btn-group btn-group-justified"> <div class="btn-group btn-group-justified">
<a href="{$trx['pg_url_payment']}" class="btn btn-primary">{Lang::T('PAY NOW')}</a> <a href="{$trx['pg_url_payment']}" target="_blank" class="btn btn-primary">{Lang::T('PAY NOW')}</a>
<a href="{$_url}order/view/{$trx['id']}/check" class="btn btn-info">{Lang::T('Check for Payment')}</a> <a href="{$_url}order/view/{$trx['id']}/check" class="btn btn-info">{Lang::T('Check for Payment')}</a>
</div> </div>
</div> </div>