UnitPaymentAccountService.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <?php
  2. namespace App\Services;
  3. use App\Exceptions\AsaasException;
  4. use App\Models\UnitPaymentAccount;
  5. use App\Services\Integrations\Asaas\AsaasWebhookService;
  6. use Illuminate\Support\Facades\Log;
  7. use Illuminate\Validation\ValidationException;
  8. class UnitPaymentAccountService
  9. {
  10. public function __construct(
  11. protected AsaasWebhookService $webhookService,
  12. ) {}
  13. public function getByUnitId(int $unitId): ?UnitPaymentAccount
  14. {
  15. return UnitPaymentAccount::where('unit_id', $unitId)->first();
  16. }
  17. /**
  18. * Cria/atualiza a conta de pagamento da unidade.
  19. *
  20. * Ao informar uma chave: valida na Asaas e registra o webhook (síncrono e
  21. * estrito — chave inválida bloqueia). Ao limpar: remove o webhook (best-effort).
  22. */
  23. public function upsertAsaasApiKey(int $unitId, ?string $apiKey): UnitPaymentAccount
  24. {
  25. $apiKey = $apiKey !== null ? trim($apiKey) : null;
  26. $hasKey = $apiKey !== null && $apiKey !== '';
  27. $model = UnitPaymentAccount::firstOrNew(['unit_id' => $unitId]);
  28. if (!$hasKey) {
  29. $this->removeWebhook($model);
  30. $model->asaas_api_key = null;
  31. $model->asaas_webhook_id = null;
  32. $model->status = UnitPaymentAccount::STATUS_PENDING;
  33. $model->onboarded_at = null;
  34. $model->save();
  35. return $model->fresh();
  36. }
  37. // Reenvio da mesma chave já configurada: mantém como está.
  38. if ($model->exists && $model->asaas_api_key === $apiKey && $model->asaas_webhook_id) {
  39. return $model->fresh();
  40. }
  41. try {
  42. $this->webhookService->validateKey($apiKey);
  43. } catch (AsaasException $e) {
  44. throw ValidationException::withMessages([
  45. 'asaas_api_key' => 'Chave Asaas inválida ou sem permissão. Verifique e tente novamente.',
  46. ]);
  47. }
  48. // Troca de chave: remove o webhook antigo antes de registrar o novo.
  49. $this->removeWebhook($model);
  50. try {
  51. $webhookId = $this->webhookService->register($apiKey);
  52. } catch (AsaasException $e) {
  53. Log::error("Falha ao registrar webhook Asaas da unidade {$unitId}: " . $e->getMessage());
  54. throw ValidationException::withMessages([
  55. 'asaas_api_key' => 'Não foi possível registrar o webhook na Asaas. Tente novamente.',
  56. ]);
  57. }
  58. $model->asaas_api_key = $apiKey;
  59. $model->asaas_webhook_id = $webhookId;
  60. $model->status = UnitPaymentAccount::STATUS_ACTIVE;
  61. $model->onboarded_at = $model->onboarded_at ?? now();
  62. $model->save();
  63. return $model->fresh();
  64. }
  65. /**
  66. * Remove o webhook atual da conta (ignora erros — best-effort).
  67. */
  68. private function removeWebhook(UnitPaymentAccount $model): void
  69. {
  70. if (!$model->asaas_api_key || !$model->asaas_webhook_id) {
  71. return;
  72. }
  73. try {
  74. $this->webhookService->delete($model->asaas_api_key, $model->asaas_webhook_id);
  75. } catch (\Throwable $e) {
  76. Log::warning("Não foi possível remover webhook Asaas da unidade {$model->unit_id}: " . $e->getMessage());
  77. }
  78. }
  79. }