|
@@ -2,10 +2,18 @@
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
namespace App\Services;
|
|
|
|
|
|
|
|
|
|
+use App\Exceptions\AsaasException;
|
|
|
use App\Models\UnitPaymentAccount;
|
|
use App\Models\UnitPaymentAccount;
|
|
|
|
|
+use App\Services\Integrations\Asaas\AsaasWebhookService;
|
|
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
|
|
+use Illuminate\Validation\ValidationException;
|
|
|
|
|
|
|
|
class UnitPaymentAccountService
|
|
class UnitPaymentAccountService
|
|
|
{
|
|
{
|
|
|
|
|
+ public function __construct(
|
|
|
|
|
+ protected AsaasWebhookService $webhookService,
|
|
|
|
|
+ ) {}
|
|
|
|
|
+
|
|
|
public function getByUnitId(int $unitId): ?UnitPaymentAccount
|
|
public function getByUnitId(int $unitId): ?UnitPaymentAccount
|
|
|
{
|
|
{
|
|
|
return UnitPaymentAccount::where('unit_id', $unitId)->first();
|
|
return UnitPaymentAccount::where('unit_id', $unitId)->first();
|
|
@@ -14,7 +22,8 @@ public function getByUnitId(int $unitId): ?UnitPaymentAccount
|
|
|
/**
|
|
/**
|
|
|
* Cria/atualiza a conta de pagamento da unidade.
|
|
* Cria/atualiza a conta de pagamento da unidade.
|
|
|
*
|
|
*
|
|
|
- * Quando a chave vem vazia, a integração é considerada limpa (status pending).
|
|
|
|
|
|
|
+ * Ao informar uma chave: valida na Asaas e registra o webhook (síncrono e
|
|
|
|
|
+ * estrito — chave inválida bloqueia). Ao limpar: remove o webhook (best-effort).
|
|
|
*/
|
|
*/
|
|
|
public function upsertAsaasApiKey(int $unitId, ?string $apiKey): UnitPaymentAccount
|
|
public function upsertAsaasApiKey(int $unitId, ?string $apiKey): UnitPaymentAccount
|
|
|
{
|
|
{
|
|
@@ -23,12 +32,65 @@ public function upsertAsaasApiKey(int $unitId, ?string $apiKey): UnitPaymentAcco
|
|
|
|
|
|
|
|
$model = UnitPaymentAccount::firstOrNew(['unit_id' => $unitId]);
|
|
$model = UnitPaymentAccount::firstOrNew(['unit_id' => $unitId]);
|
|
|
|
|
|
|
|
- $model->asaas_api_key = $hasKey ? $apiKey : null;
|
|
|
|
|
- $model->status = $hasKey ? UnitPaymentAccount::STATUS_ACTIVE : UnitPaymentAccount::STATUS_PENDING;
|
|
|
|
|
- $model->onboarded_at = $hasKey ? ($model->onboarded_at ?? now()) : null;
|
|
|
|
|
|
|
+ if (!$hasKey) {
|
|
|
|
|
+ $this->removeWebhook($model);
|
|
|
|
|
+
|
|
|
|
|
+ $model->asaas_api_key = null;
|
|
|
|
|
+ $model->asaas_webhook_id = null;
|
|
|
|
|
+ $model->status = UnitPaymentAccount::STATUS_PENDING;
|
|
|
|
|
+ $model->onboarded_at = null;
|
|
|
|
|
+ $model->save();
|
|
|
|
|
+
|
|
|
|
|
+ return $model->fresh();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Reenvio da mesma chave já configurada: mantém como está.
|
|
|
|
|
+ if ($model->exists && $model->asaas_api_key === $apiKey && $model->asaas_webhook_id) {
|
|
|
|
|
+ return $model->fresh();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $this->webhookService->validateKey($apiKey);
|
|
|
|
|
+ } catch (AsaasException $e) {
|
|
|
|
|
+ throw ValidationException::withMessages([
|
|
|
|
|
+ 'asaas_api_key' => 'Chave Asaas inválida ou sem permissão. Verifique e tente novamente.',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Troca de chave: remove o webhook antigo antes de registrar o novo.
|
|
|
|
|
+ $this->removeWebhook($model);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $webhookId = $this->webhookService->register($apiKey);
|
|
|
|
|
+ } catch (AsaasException $e) {
|
|
|
|
|
+ Log::error("Falha ao registrar webhook Asaas da unidade {$unitId}: " . $e->getMessage());
|
|
|
|
|
+ throw ValidationException::withMessages([
|
|
|
|
|
+ 'asaas_api_key' => 'Não foi possível registrar o webhook na Asaas. Tente novamente.',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ $model->asaas_api_key = $apiKey;
|
|
|
|
|
+ $model->asaas_webhook_id = $webhookId;
|
|
|
|
|
+ $model->status = UnitPaymentAccount::STATUS_ACTIVE;
|
|
|
|
|
+ $model->onboarded_at = $model->onboarded_at ?? now();
|
|
|
$model->save();
|
|
$model->save();
|
|
|
|
|
|
|
|
return $model->fresh();
|
|
return $model->fresh();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Remove o webhook atual da conta (ignora erros — best-effort).
|
|
|
|
|
+ */
|
|
|
|
|
+ private function removeWebhook(UnitPaymentAccount $model): void
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!$model->asaas_api_key || !$model->asaas_webhook_id) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $this->webhookService->delete($model->asaas_api_key, $model->asaas_webhook_id);
|
|
|
|
|
+ } catch (\Throwable $e) {
|
|
|
|
|
+ Log::warning("Não foi possível remover webhook Asaas da unidade {$model->unit_id}: " . $e->getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|