commit f0ecf26ca380b9669273e110b8e6cbd486010660 Author: NekoMonci12 Date: Wed Mar 26 17:35:31 2025 +0700 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ae96fe7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 NekoMonci12 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Photos/Cover.png b/Photos/Cover.png new file mode 100644 index 0000000..98e4016 Binary files /dev/null and b/Photos/Cover.png differ diff --git a/Photos/Example.png b/Photos/Example.png new file mode 100644 index 0000000..111890b Binary files /dev/null and b/Photos/Example.png differ diff --git a/Photos/Logo.png b/Photos/Logo.png new file mode 100644 index 0000000..900d733 Binary files /dev/null and b/Photos/Logo.png differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..52b1b1d --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +## Installation +Download the code and place it in the `app/Extensions/Gateways/Midtrans` directory. + +## Configuration +In the admin panel, go to `Settings > Payment Gateways` and click on the `Midtrans` gateway. Enter Midtrans `MerchantID`/`Server-Key`/`Client-Key` then `Save`. + +## Usage +When a user selects the `Midtrans` gateway, they will be redirected to the Midtrans payment page. After the payment is completed, the user will be redirected back to the site. + +## Setup Callback On Midtrans +1. Settings > SNAP Preferences > System Settings +``` +Finish URL = https://yourdomain.com +Unfinish URL = https://yourdomain.com +Error Payment URL = https://yourdomain.com +``` +2. Settings > Payment > Finish Redirect URL +``` +Finish Redirect URL = https://yourdomain.com +``` +3. Settings > Payment > Notification URL +``` +Notification URL = https://yourdomain.com/extensions/midtrans/webhook +Recurring payment notification URL = https://yourdomain.com +Account linking notification URL = https://yourdomain.com +``` \ No newline at end of file diff --git a/Upload/Midtrans.php b/Upload/Midtrans.php new file mode 100644 index 0000000..273083f --- /dev/null +++ b/Upload/Midtrans.php @@ -0,0 +1,134 @@ + 'Midtrans', + 'version' => '1.0.0', + 'author' => 'NekoMonci12', + 'website' => 'https://github.com/NekoMonci12', + ]; + } + + public function pay($total, $products, $invoiceId) + { + $hash = substr(hash('sha256', time()), 0, 16); + $orderId = 'PAYMENTER-' . $invoiceId . '-' . $hash; + + $serverKey = ExtensionHelper::getConfig('Midtrans', 'server_key'); + $merchantId = ExtensionHelper::getConfig('Midtrans', 'merchant_id'); + $clientKey = ExtensionHelper::getConfig('Midtrans', 'client_key'); + $debugMode = ExtensionHelper::getConfig('Midtrans', 'debug_mode'); + if ($debugMode) { + $url = 'https://app.sandbox.midtrans.com/snap/v1/transactions'; + } else { + $url = 'https://app.midtrans.com/snap/v1/transactions'; + } + $transactionDetails = [ + 'order_id' => $orderId, + 'gross_amount' => round($total, 2), + ]; + $itemDetails = []; + foreach ($products as $product) { + $itemDetails[] = [ + 'id' => $product['id'] ?? uniqid(), + 'price' => $product['price'] ?? 0, + 'quantity' => $product['quantity'] ?? 1, + 'name' => $product['name'] ?? 'Product', + ]; + } + $payload = [ + 'transaction_details' => $transactionDetails, + 'item_details' => $itemDetails, + ]; + $headers = [ + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + 'Authorization' => 'Basic ' . base64_encode($serverKey . ':'), + ]; + $response = Http::withHeaders($headers) + ->post($url, $payload); + + $responseJson = $response->json(); + if ($response->failed() || isset($responseJson['error_messages'])) { + ExtensionHelper::error('Midtrans', $responseJson); + } + + if (!isset($responseJson['redirect_url'])) { + ExtensionHelper::error('Midtrans', [ + 'error' => 'Missing redirect_url in response.', + 'response' => $responseJson, + ]); + } + + return $responseJson['redirect_url']; + } + + public function webhook(Request $request)~ + { + if (!$request->isMethod('post')) { + return response('Method Not Allowed', 405); + } + + $data = json_decode($request->getContent(), true); + if ( + isset($data['status_code'], $data['transaction_status']) && + $data['status_code'] === "200" && + in_array($data['transaction_status'], ['capture', 'settlement']) + ) { + try { + $orderId = $data['order_id']; + $parts = explode('-', $orderId); + if (count($parts) >= 3) { + $invoiceId = $parts[1]; + } else { + \Log::error('Invalid order_id format: ' . $orderId); + return response('Invalid order id format', 400); + } + ExtensionHelper::paymentDone($invoiceId, 'Midtrans', $data['transaction_id']); + } catch (\Exception $e) { + \Log::error('Error processing paymentDone: ' . $e->getMessage()); + return response('Error processing webhook', 500); + } + } + return response('OK', 200); + } + + public function getConfig() + { + return [ + [ + 'name' => 'server_key', + 'type' => 'text', + 'friendlyName' => 'Server Key', + 'required' => true, + ], + [ + 'name' => 'merchant_id', + 'type' => 'text', + 'friendlyName' => 'Merchant ID', + 'required' => true, + ], + [ + 'name' => 'client_key', + 'type' => 'text', + 'friendlyName' => 'Client Key', + 'required' => true, + ], + [ + 'name' => 'debug_mode', + 'type' => 'boolean', + 'friendlyName' => 'Should Debug Mode be enabled?', + 'required' => false, + ], + ]; + } +} diff --git a/Upload/routes.php b/Upload/routes.php new file mode 100644 index 0000000..5112b8f --- /dev/null +++ b/Upload/routes.php @@ -0,0 +1,5 @@ +name('midtrans.webhook');