Explorar el Código

feat: integração subcontas white-label Asaas (Phase 2)

ebagabee hace 1 semana
padre
commit
b17d87b70f

+ 21 - 0
app/Http/Controllers/UnitController.php

@@ -82,4 +82,25 @@ public function selectList(): JsonResponse
 
         return $this->successResponse(payload: $items);
     }
+
+    public function onboardAsaas(int $id, \App\Services\Integrations\Asaas\AsaasAccountService $asaasService): JsonResponse
+    {
+        $unit = $this->service->findById($id);
+
+        try {
+            $account = $asaasService->ensureSubaccount($unit);
+            
+            return $this->successResponse(
+                payload: $account,
+                message: 'Subconta do Asaas ativada com sucesso.',
+                code: 200
+            );
+            
+        } catch (\Exception $e) {
+            return $this->errorResponse(
+                message: 'Falha ao ativar subconta: ' . $e->getMessage(),
+                code: 400
+            );
+        }
+    }
 }

+ 5 - 0
app/Models/Unit.php

@@ -104,4 +104,9 @@ public function groups(): BelongsToMany
     {
         return $this->belongsToMany(Group::class, 'group_units');
     }
+
+    public function paymentAccount(): \Illuminate\Database\Eloquent\Relations\HasOne
+    {
+        return $this->hasOne(UnitPaymentAccount::class, 'unit_id');
+    }
 }

+ 26 - 0
app/Models/UnitPaymentAccount.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class UnitPaymentAccount extends Model
+{
+    use HasFactory;
+
+    protected $table = 'unit_payment_accounts';
+
+    protected $guarded = ['id'];
+
+    protected $casts = [
+        'onboarded_at' => 'datetime',
+        'asaas_api_key' => 'encrypted', 
+    ];
+
+    public function unit(): BelongsTo
+    {
+        return $this->belongsTo(Unit::class);
+    }
+}

+ 55 - 0
app/Services/Integrations/Asaas/AsaasAccountService.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace App\Services\Integrations\Asaas;
+
+use App\Models\Unit;
+use App\Models\UnitPaymentAccount;
+use Exception;
+
+class AsaasAccountService
+{
+    protected AsaasClient $client;
+
+    public function __construct(AsaasClient $client)
+    {
+        $this->client = $client;
+    }
+
+    public function ensureSubaccount(Unit $unit): UnitPaymentAccount
+    {
+        $existingAccount = UnitPaymentAccount::where('unit_id', $unit->id)->first();
+       
+        if ($existingAccount && $existingAccount->asaas_account_id) {
+            return $existingAccount;
+        }
+
+        if (empty($unit->cnpj)) {
+            throw new Exception("A unidade {$unit->fantasy_name} não possui um CNPJ cadastrado. O CNPJ é obrigatório para criar a subconta.");
+        }
+
+        $payload = [
+            'name' => $unit->fantasy_name ?? $unit->social_reason ?? 'Unidade Ginástica do Cérebro',
+            'email' => $unit->email,
+            'cpfCnpj' => preg_replace('/[^0-9]/', '', $unit->cnpj),
+            'mobilePhone' => preg_replace('/[^0-9]/', '', $unit->cell_number ?? $unit->phone_number ?? ''),
+            'address' => $unit->street,
+            'addressNumber' => $unit->address_number ?? 'S/N',
+            'province' => $unit->neighborhood,
+            'postalCode' => preg_replace('/[^0-9]/', '', $unit->postal_code),
+            'companyType' => 'LIMITED',
+        ];
+
+        $response = $this->client->post('/accounts', $payload);
+
+        return UnitPaymentAccount::updateOrCreate(
+            ['unit_id' => $unit->id],
+            [
+                'asaas_account_id' => $response['id'],
+                'asaas_wallet_id' => $response['walletId'],
+                'asaas_api_key' => $response['apiKey'],
+                'status' => 'ACTIVE',
+                'onboarded_at' => now(),
+            ]
+        );
+    }
+}

+ 33 - 0
database/migrations/2026_06_03_173041_create_unit_payment_accounts_table.php

@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('unit_payment_accounts', function (Blueprint $table) {
+            $table->id();
+            $table->foreignId('unit_id')->constrained('units')->onDelete('cascade');
+            $table->string('asaas_account_id')->nullable();
+            $table->string('asaas_wallet_id')->nullable();
+            $table->text('asaas_api_key')->nullable();
+            $table->string('status')->default('PENDING');
+            $table->timestamp('onboarded_at')->nullable();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('unit_payment_accounts');
+    }
+};

+ 3 - 0
routes/authRoutes/unit.php

@@ -23,6 +23,9 @@
     Route::get('/{id}', 'show')
         ->middleware('permission:unit,view');
 
+    Route::post('/{id}/asaas-onboard', 'onboardAsaas')
+        ->middleware('permission:unit,edit');
+
     Route::put('/{id}', 'update')
         ->middleware('permission:unit,edit');