midtrans pay, but not yet validated
This commit is contained in:
parent
e9d67ce220
commit
dd46273a04
65
README.md
65
README.md
@ -1,47 +1,39 @@
|
||||
# PHP Mikrotik Billing
|
||||
----
|
||||
|
||||

|
||||
## 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
|
||||
- Self registration, user must have voucher before registration
|
||||
- Multi Router Mikrotik
|
||||
- Hotspot & PPPOE
|
||||
- Easy Installation
|
||||
- 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
|
||||
- send receipt via SMS or EMAIL
|
||||
- Social Media Login
|
||||
- Rename **pages_template** to **pages
|
||||
- make writeable **system** folder or create file **system/config.php** and make it writeable
|
||||
- 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)
|
||||
|
||||
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
|
||||
|
||||
Minimum Requirements
|
||||
|
||||
- Linux or Windows OS
|
||||
- PHP Version 5.3+
|
||||
- Both PDO & MySQLi Support
|
||||
@ -51,33 +43,24 @@ Minimum Requirements
|
||||
can be Installed in Raspberry Pi Device.
|
||||
|
||||
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
|
||||
2. Raspberry Pi Server (RasPi + Casing + Memory 4GB + Adaptor)
|
||||
[Telegram](https://t.me/ibnux)
|
||||
|
||||
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
|
||||
|
||||
see LICENSE file
|
||||
|
||||
## Donate to ibnux
|
||||
|
||||
Donate to ibnux
|
||||
----
|
||||
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6RBNGRJMZVV7C)
|
||||
[](https://paypal.me/ibnux)
|
||||
|
||||
BCA: 5410454825
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
@ -91,43 +91,51 @@ switch ($action) {
|
||||
$ui->assign('_title', 'TRX #' . $trxid . ' - ' . $config['CompanyName']);
|
||||
$ui->display('user-orderView.tpl');
|
||||
break;
|
||||
case 'ppoe-buy':
|
||||
case 'hotspot-buy':
|
||||
if (empty($_c['xendit_secret_key'])) {
|
||||
r2(U . "order/hotspot", 'e', Lang::T("Admin has not yet setup Xendit payment gateway, please tell admin"));
|
||||
}
|
||||
$back = "order/".str_replace('-buy','',$action);
|
||||
$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);
|
||||
if (empty($router) || empty($plan)) {
|
||||
r2(U . "order/hotspot", 'e', Lang::T("Plan Not found"));
|
||||
r2(U . $back, 'e', Lang::T("Plan Not found"));
|
||||
}
|
||||
$d = ORM::for_table('tbl_payment_gateway')
|
||||
->where('username', $user['username'])
|
||||
->where('status', 1)
|
||||
->find_one();
|
||||
if ($d['pg_url_payment']) {
|
||||
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'];
|
||||
}else{
|
||||
$d->status = 4;
|
||||
$d->save();
|
||||
}
|
||||
}
|
||||
if(empty($id)){
|
||||
$d = ORM::for_table('tbl_payment_gateway')->create();
|
||||
$d->username = $user['username'];
|
||||
$d->gateway = $_c['payment_gateway'];
|
||||
$d->plan_id = $plan['id'];
|
||||
$d->plan_name = $plan['name_plan'];
|
||||
$d->routers_id = $router['id'];
|
||||
$d->routers = $router['name'];
|
||||
$d->price = $plan['price'];
|
||||
$d->created_date = date('Y-m-d H:i:s');
|
||||
$d->status = 1;
|
||||
$d->save();
|
||||
$id = $d->id();
|
||||
}
|
||||
if ($_c['payment_gateway'] == 'xendit') {
|
||||
$d = ORM::for_table('tbl_payment_gateway')
|
||||
->where('username', $user['username'])
|
||||
->where('status', 1)
|
||||
->find_one();
|
||||
if ($d) {
|
||||
if ($d['pg_url_payment']) {
|
||||
r2(U . "order/view/" . $d['id'], 'w', Lang::T("You already have unpaid transaction, cancel it or pay it."));
|
||||
}
|
||||
$id = $d['id'];
|
||||
} else {
|
||||
$d = ORM::for_table('tbl_payment_gateway')->create();
|
||||
$d->username = $user['username'];
|
||||
$d->gateway = 'xendit';
|
||||
$d->plan_id = $plan['id'];
|
||||
$d->plan_name = $plan['name_plan'];
|
||||
$d->routers_id = $router['id'];
|
||||
$d->routers = $router['name'];
|
||||
$d->price = $plan['price'];
|
||||
$d->created_date = date('Y-m-d H:i:s');
|
||||
$d->status = 1;
|
||||
$d->save();
|
||||
$id = $d->id();
|
||||
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) {
|
||||
$result = xendit_create_invoice($id, $plan['price'], $user['username'], $plan['name_plan']);
|
||||
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')
|
||||
->where('username', $user['username'])
|
||||
@ -144,7 +152,34 @@ switch ($action) {
|
||||
r2(U . "order/view/" . $d['id'], 'w', Lang::T("Failed to create Transaction.."));
|
||||
}
|
||||
} 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') {
|
||||
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;
|
||||
default:
|
||||
|
@ -272,3 +272,5 @@ $_L['Transaction_still_unpaid'] = 'Transaction still unpaid.';
|
||||
$_L['Paid_Date'] = 'Paid Date';
|
||||
$_L['Transaction_has_been_paid'] = 'Transaction has been paid.';
|
||||
$_L['PAID'] = 'PAID';
|
||||
$_L['Buy_Hotspot_Plan'] = 'Buy Hotspot Plan';
|
||||
$_L['Buy_PPOE_Plan'] = 'Buy PPOE Plan';
|
||||
|
@ -30,6 +30,7 @@
|
||||
<div class="col-md-6">
|
||||
<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">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>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -21,6 +21,7 @@
|
||||
<label class="col-md-2 control-label">{$_L['Plan_Name']}</label>
|
||||
<div class="col-md-6">
|
||||
<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 class="form-group">
|
||||
@ -63,6 +64,7 @@
|
||||
<option value="{$rs['name']}">{$rs['name']}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
<p class="help-block">{Lang::T('Cannot be change after saved')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -137,7 +137,7 @@
|
||||
</a>
|
||||
<ul class="inner-drop list-unstyled">
|
||||
<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/ppoe">PPOE</a></li>
|
||||
{/if}
|
||||
|
@ -45,6 +45,14 @@
|
||||
<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>
|
||||
</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 class="col-md-6">
|
||||
|
@ -1,27 +1,45 @@
|
||||
{include file="sections/user-header.tpl"}
|
||||
<div class="row">
|
||||
<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>
|
||||
{foreach $routers as $router}
|
||||
<div class="panel mb20 panel-info panel-hovered">
|
||||
<div class="panel-heading">{$router['name']}</div>
|
||||
<div class="panel-body">
|
||||
{$router['description']}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-3">
|
||||
<div class="panel mb10 panel-default panel-hovered">
|
||||
<div class="panel-heading">Router Name</div>
|
||||
<div class="panel-body">
|
||||
Router Description
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="" class="btn btn-sm btn-block btn-primary">Buy</a>
|
||||
</div>
|
||||
{if $router['description'] != ''}
|
||||
<div class="panel-body">
|
||||
{$router['description']}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="panel-body row">
|
||||
{foreach $plans as $plan}
|
||||
{if $router['name'] eq $plan['routers']}
|
||||
<div class="col-sm-3">
|
||||
<div class="panel mb10 panel-default panel-hovered">
|
||||
<div class="panel-heading"> {$plan['name_plan']}</div>
|
||||
<div class="table-responsive">
|
||||
<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 class="panel-footer">
|
||||
<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>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
|
@ -75,8 +75,8 @@
|
||||
{if $trx['status']==1}
|
||||
<div class="panel-footer ">
|
||||
<div class="btn-group btn-group-justified">
|
||||
<a href="{$trx['pg_url_payment']}" 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="{$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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer ">
|
||||
|
Loading…
x
Reference in New Issue
Block a user