dockerize + release edits

This commit is contained in:
t0is 2025-06-18 10:58:31 +02:00
parent 8eebaf8819
commit 4a48b29e50
11 changed files with 306 additions and 432 deletions

7
.dockerignore Normal file
View File

@ -0,0 +1,7 @@
/.git
/.idea
/.env
/vendor
/node_modules
/storage/**/*.php
/storage/**/*.log

22
Dockerfile Normal file
View File

@ -0,0 +1,22 @@
# ./Dockerfile
FROM php:8.2-cli
# install system deps & PHP extensions
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
git unzip libzip-dev libpng-dev libonig-dev libxml2-dev \
&& docker-php-ext-install pdo_mysql mbstring zip exif pcntl bcmath gd \
&& rm -rf /var/lib/apt/lists/*
# install composer
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
WORKDIR /var/www
# copy app & install deps
COPY . /var/www
RUN composer install --no-dev --optimize-autoloader
# expose port and use built-in server; change 8000 if you like
CMD ["php", "-S", "0.0.0.0:8007", "-t", "public"]

View File

@ -40,14 +40,14 @@ class TransactionController extends Controller
$order = Order::where('orders_id', $orderId)->first();
$billingName = explode(" ",$order->billing_name,2);
$sale = $gateway->transaction()->sale([
'amount' => $order->order_total,
'amount' => round($order->order_total*$order->currency_value, 2),
'paymentMethodNonce' => $nonce,
'orderId' => $orderId,
//'merchantAccountId' => $order->currency
'customer' => [
'firstName' => $order->customers_firstname,
'lastName' => $order->customers_firstname,
'email' => "test" . $order->customers_email_address,
'email' => $order->customers_email_address,
'phone' => $order->customers_telephone,
],
'billing' => [
@ -69,12 +69,28 @@ class TransactionController extends Controller
$this->newTransactionDb($transaction, $orderId);
if ($sale->success) {
$settlementResult = $gateway->transaction()->submitForSettlement($transaction->id);
$this->updateStatusDb($settlementResult->transaction, $settlementResult->transaction->status);
BraintreePaymentStatus::create([
'transaction_id' => $settlementResult->transaction->id,
'status_name' => $settlementResult->transaction->status,
]);
OrdersStatusHistory::create([
'orders_id' => $orderId,
'orders_status_id' => 5, // waiting to be processed
'customer_notified' => -1,
'comments' => "Braintree -- " . $settlementResult->transaction->status,
]);
return response()->json(['success' => true, 'transaction' => $settlementResult->transaction ?? $transaction]);
}
return response()->json(['success' => true, 'transaction' => $settlementResult ?? $transaction]);
else {
return response()->json(['success' => false, 'sale_result' => $sale]);
}
}
catch (\Exception $e) {
return response()->json(['success' => false, 'message' => 'Error: nonce:'. $nonce . ', amount: ' . $amount . $e->getMessage()], 500);
return response()->json(['success' => false, 'message' => 'Error: nonce:'. $nonce . ' ----- ' . $e->getMessage()], 500);
}
}
@ -128,22 +144,13 @@ class TransactionController extends Controller
public function newTransactionDb($transaction, $orderId): void
{
OrdersStatusHistory::create([
'orders_id'=>$orderId,
'orders_status_id'=> 44,
'customer_notified'=>1,
'comments'=>$transaction->status,
'hidden'=>0,
'highlight'=>0,
'message_msg'=>'not yet analyzed',
'message_provider'=>'vat'
]);
BraintreePayment::create([
'transaction_id'=>$transaction->id,
'orders_id'=> $orderId,
'total'=>$transaction->amount,
'currency'=>$transaction->currencyIsoCode
]);
BraintreePaymentStatus::create([
'transaction_id'=>$transaction->id,
'status_id'=> $transaction->processorResponseCode,
@ -153,20 +160,4 @@ class TransactionController extends Controller
]);
}
public function updateStatusDb($transaction) {
BraintreePaymentStatus::create([
'transaction_id'=>$transaction->id,
'status_name'=>$transaction->status,
]);
OrdersStatusHistory::create([
'orders_id'=>$transaction->orderId,
'orders_status_id'=> 44,
'customer_notified'=>1,
'comments'=>$transaction->status,
'hidden'=>0,
'highlight'=>0,
'message_msg'=>'not yet analyzed',
'message_provider'=>'vat'
]);
}
}

View File

@ -9,6 +9,7 @@ use App\Models\OrdersStatusHistory;
use Braintree\Exception\InvalidSignature;
use Braintree\Gateway;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Http;
@ -22,7 +23,7 @@ class WebhookController extends Controller
$this->gateway = $gateway;
}
public function testWebhook(Request $request): \Illuminate\Http\JsonResponse
public function testWebhook(Request $request): JsonResponse
{
try {
$sampleNotification = $this->gateway->webhookTesting()->sampleNotification(
@ -37,9 +38,8 @@ class WebhookController extends Controller
]);
// Call your actual webhook handler
$this->handle($webhookRequest);
return $this->handle($webhookRequest);
return response()->json(['success' => true]);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
@ -48,7 +48,7 @@ class WebhookController extends Controller
/**
* @throws InvalidSignature
*/
public function handle(Request $request): Response|ResponseFactory
public function handle(Request $request): JsonResponse
{
$webhookNotification = $this->gateway->webhookNotification()->parse(
$request->input('bt_signature'),
@ -57,46 +57,30 @@ class WebhookController extends Controller
Log::channel('braintree')->info('Webhook ', ['kind' => $webhookNotification->kind]);
Log::channel('braintree')->info('Webhook ', ['timestamp' => $webhookNotification->timestamp]);
Log::channel('braintree')->info('Webhook ', ['transaction' => $webhookNotification->transaction ?? null]);
Log::channel('braintree')->info('Webhook ', ['subscription' => $webhookNotification->subscription ?? null]);
Log::channel('braintree')->info('', []);
try {
$webhookTrans = $webhookNotification->subject['transaction'];
$status = '';
if($refund = BraintreePaymentRefund::where('refund_id', $webhookTrans['id'])->first()){
if ($refund = BraintreePaymentRefund::where('refund_id', $webhookTrans['id'])->first()) {
$origTrans = BraintreePayment::where('transaction_id', $refund->transaction_id)->first();
$status = 'refund_';
$is_refund = true;
} else {
$origTrans = BraintreePayment::where('transaction_id', $webhookTrans['id'])->first();
}
switch ($webhookNotification->kind) {
case 'transaction_settled': {
$status = $status . 'settled';
}break;
case 'transaction_disbursed': {
$status = $status . 'disbursed';
} break;
case 'transaction_settlement_declined': {
$status = $status . 'settlement_declined';
}
}
$this->updateStatusDb($origTrans, $status);
return response('', 200);
$is_refund = false;
}
public function updateStatusDb($transaction, $status) {
BraintreePaymentStatus::create([
'transaction_id'=>$transaction->transaction_id,
'status_name'=>$status,
]);
OrdersStatusHistory::create([
'orders_id'=>$transaction->orders_id,
'orders_status_id'=> 44,
'customer_notified'=>1,
'comments'=>$status,
'hidden'=>0,
'highlight'=>0,
'message_msg'=>'not yet analyzed',
'message_provider'=>'vat'
'transaction_id' => $origTrans->transaction_id,
'status_name' => ($is_refund ? "refund_" : "") . $webhookNotification->kind,
]);
return response()->json('', 200);
}
catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
}

View File

@ -27,6 +27,6 @@ class BraintreePayment extends Model
public function order(): belongsTo
{
return $this->belongsTo(Order::class, 'order_id');
return $this->belongsTo(Order::class, 'orders_id');
}
}

View File

@ -9,7 +9,7 @@ class BraintreePaymentStatus extends Model
{
protected $table = 'rcd_braintree_payment_status';
public $timestamps = true;
const UPDATED_AT = null;
protected $guarded = [];
public function braintreePayment(): belongsTo

501
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -31,36 +31,6 @@ return [
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DB_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
'busy_timeout' => null,
'journal_mode' => null,
'synchronous' => null,
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'mariadb' => [
'driver' => 'mariadb',
@ -82,36 +52,6 @@ return [
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DB_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => env('DB_CHARSET', 'utf8'),
'prefix' => '',
'prefix_indexes' => true,
'search_path' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DB_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => env('DB_CHARSET', 'utf8'),
'prefix' => '',
'prefix_indexes' => true,
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
],
],
/*

22
docker-compose.yml Normal file
View File

@ -0,0 +1,22 @@
services:
api:
build:
context: .
dockerfile: Dockerfile
image: laravel-api:latest
container_name: laravel-api
restart: always
env_file:
- .env
ports:
- "8007:8007"
networks:
- traefik
- maxscale
networks:
mysql:
external: true
traefik:
external: true

2
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "platebniBrana",
"name": "braintree_api",
"lockfileVersion": 3,
"requires": true,
"packages": {

View File

@ -10,4 +10,5 @@ Route::post('/generateToken', [TransactionController::class, 'generateToken']);
Route::post('/startRefund', [TransactionController::class, 'startRefund']);
Route::post('/settle', [TransactionController::class, 'settle']);
Route::post('/void', [TransactionController::class, 'void']);
Route::post('/testWebhook', [WebhookController::class, 'testWebhook']);