Version 1.0 #102

Merged
FernandoJVideira merged 163 commits from develop into master 2026-01-03 14:49:00 +00:00
3 changed files with 113 additions and 0 deletions
Showing only changes of commit 5975208877 - Show all commits
@@ -0,0 +1,77 @@
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\CoinPurchase;
use App\Models\CoinTransaction;
use App\Models\CoinTransactionType;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class CoinPurchaseController extends Controller
{
public function store(Request $request)
{
$validated = $request->validate([
'euros' => 'required|numeric|min:1|max:100',
'payment_type' => 'required|in:MBWAY,IBAN,MB,VISA,PAYPAL',
'payment_reference' => [
'required',
function ($attribute, $value, $fail) use ($request) {
$type = $request->payment_type;
$regex = null;
switch ($type) {
case 'MBWAY': $regex = '/^9[0-9]{8}$/'; break;
case 'IBAN': $regex = '/^[A-Z]{2}[0-9]{23}$/'; break;
case 'MB': $regex = '/^[0-9]{5}-[0-9]{9}$/'; break;
case 'VISA': $regex = '/^4[0-9]{15}$/'; break;
case 'PAYPAL':
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$fail("Invalid PayPal email.");
}
return;
}
if ($regex && !preg_match($regex, $value)) {
$fail("Invalid format for $type.");
}
},
],
]);
$user = $request->user();
$coinsAmount = $validated['euros'] * 10;
return DB::transaction(function () use ($user, $validated, $coinsAmount) {
$type = CoinTransactionType::firstOrCreate(['name' => 'Coin purchase'], ['type' => 'C']);
$transaction = CoinTransaction::create([
'user_id' => $user->id,
'coin_transaction_type_id' => $type->id,
'transaction_datetime' => now(),
'coins' => $coinsAmount,
]);
$purchase = CoinPurchase::create([
'purchase_datetime' => now(),
'user_id' => $user->id,
'coin_transaction_id' => $transaction->id,
'euros' => $validated['euros'],
'payment_type' => $validated['payment_type'],
'payment_reference' => $validated['payment_reference'],
]);
$user->increment('coins_balance', $coinsAmount);
return response()->json([
'message' => 'Purchase successful',
'balance' => $user->coins_balance,
'transaction_id' => $transaction->id,
'purchase' => $purchase,
], 201);
});
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CoinPurchase extends Model
{
use HasFactory;
protected $table = 'coin_purchases';
public $timestamps = false;
protected $fillable = [
'purchase_datetime',
'user_id',
'coin_transaction_id',
'euros',
'payment_type',
'payment_reference',
'custom'
];
protected $casts = [
'purchase_datetime' => 'datetime',
'custom' => 'array',
];
public function transaction()
{
return $this->belongsTo(CoinTransaction::class, 'coin_transaction_id');
}
}
+2
View File
@@ -6,6 +6,7 @@ use App\Http\Controllers\MatchController;
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\StatisticsController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\CoinPurchaseController;
use Illuminate\Support\Facades\Route;
Route::prefix('v1')->group(function () {
@@ -19,6 +20,7 @@ Route::prefix('v1')->group(function () {
// Authenticated Routes
Route::middleware(['auth:sanctum', 'throttle:60,1'])->group(function () {
Route::post('/logout', [AuthController::class, 'logout']);
Route::post('/coin-purchases', [CoinPurchaseController::class, 'store']);
Route::get('/statistics/me', [StatisticsController::class, 'getPersonalStats']);
Route::prefix('users/me')->group(function () {
Route::get('/', [ProfileController::class, 'show']);