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
----
![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
- 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
----
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6RBNGRJMZVV7C)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/ibnux)
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)
{
$ch = curl_init();

View File

@ -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:

View File

@ -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';

View File

@ -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>

View File

@ -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">

View File

@ -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}

View File

@ -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">

View File

@ -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}

View File

@ -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 ">