Skip to content

Commit 4ed706d

Browse files
committed
Merge branch 'payment-gateway'
2 parents e8fabb4 + 14a3332 commit 4ed706d

18 files changed

+368
-85
lines changed

.env.example

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,10 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
5454

5555
GOOGLE_CLIENT_ID =
5656
GOOGLE_CLIENT_SECRET =
57-
GOOGLE_CLIENT_REDIRECT =
57+
GOOGLE_CLIENT_REDIRECT =
58+
59+
MIDTRANS_SERVERKEY =
60+
MIDTRANS_CLIENTKEY =
61+
MIDTRANS_IS_PRODUCTION = false
62+
MIDTRANS_IS_SANITIZE = false
63+
MIDTRANS_3DS = false

app/Http/Controllers/User/CheckoutController.php

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,22 @@
77
use Illuminate\Http\Request;
88
use App\Http\Controllers\Controller;
99
use App\Http\Requests\User\Checkout\Store;
10+
use App\Mail\Checkout\AfterCheckout;
1011
use Auth;
1112
use Mail;
12-
use App\Mail\Checkout\AfterCheckout;
13+
use Str;
14+
use Midtrans;
1315

1416
class CheckoutController extends Controller
1517
{
18+
public function __construct()
19+
{
20+
Midtrans\Config::$serverKey = env('MIDTRANS_SERVERKEY');
21+
Midtrans\Config::$isProduction = env('MIDTRANS_IS_PRODUCTION');
22+
Midtrans\Config::$isSanitized = env('MIDTRANS_IS_SANITIZED');
23+
Midtrans\Config::$is3ds = env('MIDTRANS_IS_3DS');
24+
}
25+
1626
/**
1727
* Display a listing of the resource.
1828
*
@@ -59,10 +69,12 @@ public function store(Store $request, Camp $camp)
5969
$user->email = $data['email'];
6070
$user->name = $data['name'];
6171
$user->occupation = $data['occupation'];
72+
$user->phone = $data['phone'];
6273
$user->save();
6374

6475
// create checkout
6576
$checkout = Checkout::create($data);
77+
$this->getSnapRedirect($checkout);
6678

6779
// Setting Email
6880
Mail::to(Auth::user()->email)->send(new AfterCheckout($checkout));
@@ -126,4 +138,113 @@ public function success(Checkout $checkout)
126138
return view('checkout.success');
127139
}
128140

141+
/**
142+
* Midtrans handler
143+
*/
144+
public function getSnapRedirect(Checkout $checkout)
145+
{
146+
$orderId = $checkout->id.'-'.Str::random(5);
147+
$price = $checkout->Camp->price * 1000;
148+
$checkout->midtrans_booking_code = $orderId;
149+
150+
$transaction_details = [
151+
'order_id' => $orderId,
152+
'gross_amount' => $price
153+
];
154+
155+
$item_details[] = [
156+
'id' => $orderId,
157+
'price' => $price,
158+
'quantity' => 1,
159+
'name' => "Payment for {$checkout->Camp->title}"
160+
];
161+
162+
$userData = [
163+
'first_name' => $checkout->User->name,
164+
'last_name' => '',
165+
'address' => '',
166+
'city' => '',
167+
'postal_code' => '',
168+
'phone' => $checkout->User->phone,
169+
'country_code' => "IDN"
170+
];
171+
172+
$customer_details = [
173+
"first_name" => $checkout->User->name,
174+
"last_name" => "",
175+
"email" => $checkout->User->email,
176+
"phone" => $checkout->User->phone,
177+
"billing_address" => $userData,
178+
"shipping_address" => $userData
179+
];
180+
181+
$midtrans_params = [
182+
'transaction_details' => $transaction_details,
183+
'customer_details' => $customer_details,
184+
'item_details' => $item_details
185+
];
186+
187+
try {
188+
//Get Snap Payment Page URL
189+
$paymentUrl = \Midtrans\Snap::createTransaction($midtrans_params)->redirect_url;
190+
$checkout->midtrans_url = $paymentUrl;
191+
$checkout->save();
192+
193+
return $paymentUrl;
194+
; } catch (Exception $e) {
195+
return false;
196+
}
197+
}
198+
199+
public function midtransCallback(Request $request)
200+
{
201+
$notif = $request->method() == 'POST' ? new Midtrans\Notification() : Midtrans\Transaction::status($request->order_id);
202+
203+
$transaction_status = $notif->transaction_status;
204+
$fraud = $notif->fraud_status;
205+
206+
$checkout_id = explode('-', $notif->order_id)[0];
207+
$checkout = Checkout::find($checkout_id);
208+
209+
if ($transaction_status == 'capture') {
210+
if ($fraud == 'challenge') {
211+
// TODO Set payment status in merchant's database to 'challenge'
212+
$checkout->payment_status = 'pending';
213+
}
214+
else if ($fraud == 'accept') {
215+
// TODO Set payment status in merchant's database to 'success'
216+
$checkout->payment_status = 'paid';
217+
}
218+
}
219+
else if ($transaction_status == 'cancel') {
220+
if ($fraud == 'challenge') {
221+
// TODO Set payment status in merchant's database to 'failure'
222+
$checkout->payment_status = 'failed';
223+
}
224+
else if ($fraud == 'accept') {
225+
// TODO Set payment status in merchant's database to 'failure'
226+
$checkout->payment_status = 'failed';
227+
}
228+
}
229+
else if ($transaction_status == 'deny') {
230+
// TODO Set payment status in merchant's database to 'failure'
231+
$checkout->payment_status = 'failed';
232+
}
233+
else if ($transaction_status == 'settlement') {
234+
// TODO set payment status in merchant's database to 'Settlement'
235+
$checkout->payment_status = 'paid';
236+
}
237+
else if ($transaction_status == 'pending') {
238+
// TODO set payment status in merchant's database to 'Pending'
239+
$checkout->payment_status = 'pendiing';
240+
}
241+
else if ($transaction_status == 'expire') {
242+
// TODO set payment status in merchant's database to 'expire'
243+
$checkout->payment_status = 'failed';
244+
}
245+
246+
$checkout->save();
247+
return view('checkout/success');
248+
}
249+
129250
}

app/Http/Middleware/VerifyCsrfToken.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware
1212
* @var array<int, string>
1313
*/
1414
protected $except = [
15-
//
15+
'payment/success'
1616
];
1717
}

app/Http/Requests/User/Checkout/Store.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ public function rules()
2929
'name' => 'required|string',
3030
'email' => 'required|email|unique:users,email,'.Auth::id().',id',
3131
'occupation' => 'required|string',
32-
'card_number' => 'required|numeric|digits_between:8,16',
33-
'expired' => 'required|date|date_format:Y-m|after_or_equal:'.$expiredValidation,
34-
'cvc' => 'required|numeric|digits:3'
32+
'phone' => 'required|numeric|digits_between:10,13'
3533
];
3634
}
3735
}

app/Models/Checkout.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ class Checkout extends Model
1313

1414
protected $fillable = [
1515
'user_id',
16-
'camp_id',
17-
'card_number',
18-
'expired',
19-
'cvc',
20-
'is_paid'
16+
'camp_id',
17+
'payment_status',
18+
'midtrans_url',
19+
'midtrans_booking_code'
2120
];
2221

23-
public function setExpiredAttribute($value)
24-
{
25-
$this->attributes['expired'] =date('Y-m-t', strtotime($value));
26-
}
22+
// Dah Kaga dipake
23+
// public function setExpiredAttribute($value)
24+
// {
25+
// $this->attributes['expired'] =date('Y-m-t', strtotime($value));
26+
// }
2727

2828
/**
2929
* Get the Camp that owns the Checkout

app/Models/User.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class User extends Authenticatable
2424
'password',
2525
'avatar',
2626
'occupation',
27+
'phone',
2728
'is_admin',
2829
'email_verified_at'
2930
];

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"laravel/framework": "^8.75",
1313
"laravel/sanctum": "^2.11",
1414
"laravel/socialite": "^5.6",
15-
"laravel/tinker": "^2.5"
15+
"laravel/tinker": "^2.5",
16+
"midtrans/midtrans-php": "^2.5"
1617
},
1718
"require-dev": {
1819
"facade/ignition": "^2.5",

composer.lock

Lines changed: 56 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class RemoveCardNumberAndExpiredAndCvcAndIsPaidInCheckoutsTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('checkouts', function (Blueprint $table) {
17+
$table->dropColumn(
18+
[
19+
'card_number',
20+
'expired',
21+
'cvc',
22+
'is_paid'
23+
]);
24+
});
25+
}
26+
27+
/**
28+
* Reverse the migrations.
29+
*
30+
* @return void
31+
*/
32+
public function down()
33+
{
34+
Schema::table('checkouts', function (Blueprint $table) {
35+
$table->string('card_number', 20)->nullable();
36+
$table->date('expired')->nullable();
37+
$table->string('cvc', 3)->nullable();
38+
// is_paid default false karena setelah checkout tidak langsung bayar
39+
$table->boolean('is_paid')->default(false);
40+
});
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class AddPaymentStatusAndMidtransUrlAndMidtransBookingCodeInCheckoutsTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('checkouts', function (Blueprint $table) {
17+
$table->string('payment_status', 100)->default('waiting')->after('camp_id');
18+
$table->string('midtrans_url')->nullable()->after('payment_status');
19+
$table->string('midtrans_booking_code')->nullable()->after('midtrans_url');
20+
});
21+
}
22+
23+
/**
24+
* Reverse the migrations.
25+
*
26+
* @return void
27+
*/
28+
public function down()
29+
{
30+
Schema::table('checkouts', function (Blueprint $table) {
31+
$table->dropColumn(
32+
[
33+
'payment_status',
34+
'midtrans_url',
35+
'midtrans_booking_code'
36+
]
37+
);
38+
});
39+
}
40+
}

0 commit comments

Comments
 (0)