Jelajahi Sumber

refactor: utiliza facade http na service de criacao de recipient da integracao com pagarme + adicao de logs para o pagarme na configuracao

Gustavo Mantovani 4 minggu lalu
induk
melakukan
f9e9ee0070

+ 42 - 35
app/Http/Requests/RegisterProviderRequest.php

@@ -11,43 +11,47 @@ class RegisterProviderRequest extends FormRequest
   public function rules(): array
   {
     $rules = [
-      'email' => 'sometimes|email',
-      'phone' => 'sometimes|string|nullable|max:20',
-      'name' => 'required|string|max:255',
-      'code' => 'required|string|max:6',
-      'document' => ['required', 'string', 'max:20'],
-      'rg' => 'required|string|max:20',
+      'email'      => 'sometimes|email',
+      'phone'      => 'sometimes|string|nullable|max:20',
+      'name'       => 'required|string|max:255',
+      'code'       => 'required|string|max:6',
+      'document'   => ['required', 'string', 'max:20'],
+      'rg'         => 'required|string|max:20',
       'birth_date' => 'required|date|before:today',
-      'recipient_name' => 'required|string|max:255',
-      'recipient_email' => 'required|email|max:255',
+
+      'recipient_name'        => 'required|string|max:255',
+      'recipient_email'       => 'required|email|max:255',
       'recipient_description' => 'required|string',
-      'recipient_document' => 'required|string|max:20',
-      'recipient_type' => ['required', Rule::in(['individual', 'company'])],
-      'recipient_code' => 'required|string|max:255',
+      'recipient_document'    => 'required|string|max:20',
+      'recipient_type'        => ['required', Rule::in(['individual', 'company'])],
+      'recipient_code'        => 'required|string|max:255',
+
       'recipient_payment_mode' => ['required', Rule::in(['bank_transfer'])],
-      'recipient_default_bank_account' => 'required|array',
-      'recipient_default_bank_account.holder_name' => 'required|string|max:255',
-      'recipient_default_bank_account.holder_type' => ['required', Rule::in(['individual', 'company'])],
-      'recipient_default_bank_account.holder_document' => 'required|string|max:20',
-      'recipient_default_bank_account.bank' => 'required|string|max:20',
-      'recipient_default_bank_account.branch_number' => 'required|string|max:20',
-      'recipient_default_bank_account.branch_check_digit' => 'sometimes|nullable|string|max:10',
-      'recipient_default_bank_account.account_number' => 'required|string|max:20',
+
+      'recipient_default_bank_account'                     => 'required|array',
+      'recipient_default_bank_account.holder_name'         => 'required|string|max:255',
+      'recipient_default_bank_account.holder_type'         => ['required', Rule::in(['individual', 'company'])],
+      'recipient_default_bank_account.holder_document'     => 'required|string|max:20',
+      'recipient_default_bank_account.bank'                => 'required|string|max:20',
+      'recipient_default_bank_account.branch_number'       => 'required|string|max:20',
+      'recipient_default_bank_account.branch_check_digit'  => 'sometimes|nullable|string|max:10',
+      'recipient_default_bank_account.account_number'      => 'required|string|max:20',
       'recipient_default_bank_account.account_check_digit' => 'required|string|max:10',
-      'recipient_default_bank_account.type' => ['required', Rule::in(['checking', 'savings'])],
-      'recipient_default_bank_account.metadata' => 'required|array',
-      'recipient_default_bank_account.pix_key' => 'sometimes|nullable|string|max:255',
-      'recipient_metadata' => 'required|array',
+      'recipient_default_bank_account.type'                => ['required', Rule::in(['checking', 'savings'])],
+      'recipient_default_bank_account.metadata'            => 'sometimes|array',
+      'recipient_default_bank_account.pix_key'             => 'sometimes|nullable|string|max:255',
+
+      'recipient_metadata' => 'sometimes|array',
 
-      'zip_code' => 'required|string|max:20',
-      'address' => 'required|string|max:255',
+      'zip_code'       => 'required|string|max:20',
+      'address'        => 'required|string|max:255',
       'has_complement' => 'sometimes|boolean',
-      'complement' => 'nullable|string|max:255',
-      'nickname' => 'nullable|string|max:255',
-      'instructions' => 'nullable|string',
-      'address_type' => ['required', Rule::in(['home', 'commercial', 'other'])],
-      'city' => 'nullable|string|max:255',
-      'state' => 'nullable|string|max:2',
+      'complement'     => 'nullable|string|max:255',
+      'nickname'       => 'nullable|string|max:255',
+      'instructions'   => 'nullable|string',
+      'address_type'   => ['required', Rule::in(['home', 'commercial', 'other'])],
+      'city'           => 'nullable|string|max:255',
+      'state'          => 'nullable|string|max:2',
 
       'daily_price_8h' => 'required|numeric|min:100|max:500',
       'daily_price_6h' => 'required|numeric|min:0',
@@ -55,13 +59,16 @@ class RegisterProviderRequest extends FormRequest
       'daily_price_2h' => 'required|numeric|min:0',
 
       'services_types_ids' => 'sometimes|array',
+
       'services_types_ids.*' => [
         'integer',
         Rule::exists('service_types', 'id')->where(function ($query) {
           $query->whereNull('deleted_at')->where('is_active', true);
         }),
       ],
+
       'service_types_ids' => 'sometimes|array',
+
       'service_types_ids.*' => [
         'integer',
         Rule::exists('service_types', 'id')->where(function ($query) {
@@ -69,13 +76,13 @@ class RegisterProviderRequest extends FormRequest
         }),
       ],
 
-      'working_days' => 'required|array|min:1',
-      'working_days.*.day' => 'required|integer|min:0|max:6',
+      'working_days'          => 'required|array|min:1',
+      'working_days.*.day'    => 'required|integer|min:0|max:6',
       'working_days.*.period' => ['required', Rule::in([WorkingPeriodEnum::MORNING->value, WorkingPeriodEnum::AFTERNOON->value])],
 
-      'selfie_base64' => 'required|string',
+      'selfie_base64'         => 'required|string',
       'document_front_base64' => 'required|string',
-      'document_back_base64' => 'required|string',
+      'document_back_base64'  => 'required|string',
     ];
 
     if (!$this->has('email')) {

+ 102 - 87
app/Services/Pagarme/PagarmeRecipientService.php

@@ -3,88 +3,94 @@
 namespace App\Services\Pagarme;
 
 use App\Models\Provider;
-use PagarmeApiSDKLib\Authentication\BasicAuthCredentialsBuilder;
-use PagarmeApiSDKLib\Models\Builders\CreateBankAccountRequestBuilder;
-use PagarmeApiSDKLib\Models\Builders\CreateRecipientRequestBuilder;
-use PagarmeApiSDKLib\Models\Builders\CreateTransferSettingsRequestBuilder;
-use PagarmeApiSDKLib\Models\Builders\UpdateAutomaticAnticipationSettingsRequestBuilder;
-use PagarmeApiSDKLib\PagarmeApiSDKClient;
-use PagarmeApiSDKLib\PagarmeApiSDKClientBuilder;
+use Illuminate\Support\Facades\Http;
+use Illuminate\Support\Facades\Log;
 
 class PagarmeRecipientService
 {
-    private ?PagarmeApiSDKClient $client = null;
-
     public function createRecipientForProvider(Provider $provider, array $data): string
     {
         if (!empty($provider->recipient_id)) {
             return $provider->recipient_id;
         }
 
-        $client = $this->client();
         $bankAccountData = $data['recipient_default_bank_account'];
-        $metadata = $data['recipient_metadata'] ?? [];
-        $paymentMode = $data['recipient_payment_mode'];
-
-        $bankAccount = CreateBankAccountRequestBuilder::init(
-            $bankAccountData['holder_name'],
-            $bankAccountData['holder_type'],
-            $bankAccountData['holder_document'],
-            $bankAccountData['bank'],
-            $bankAccountData['branch_number'],
-            $bankAccountData['account_number'],
-            $bankAccountData['account_check_digit'],
-            $bankAccountData['type'],
-            $bankAccountData['metadata'] ?? []
-        )
-            ->branchCheckDigit($bankAccountData['branch_check_digit'] ?? null)
-            ->pixKey($bankAccountData['pix_key'] ?? null)
-            ->build();
-
-        $recipientRequest = CreateRecipientRequestBuilder::init(
-            $bankAccount,
-            $metadata,
-            $data['recipient_code'],
-            $paymentMode
-        )
-            ->name($data['recipient_name'])
-            ->email($data['recipient_email'])
-            ->description($data['recipient_description'])
-            ->document($data['recipient_document'])
-            ->type($data['recipient_type']);
-
-        $recipientTransferSettings = CreateTransferSettingsRequestBuilder::init(false, 'daily', 0)->build();
-
-        $recipientRequest->transferSettings($recipientTransferSettings);
-
-        $recipient = $client->getRecipientsController()->createRecipient(
-            $recipientRequest->build(),
-            $this->idempotencyKey($provider->id)
-        );
-
-        $recipientId = $recipient->getId();
+        $metadata        = $data['recipient_metadata'] ?? [];
+        $paymentMode     = $data['recipient_payment_mode'];
+
+        $response = $this->pagarmeRequest($provider->id)
+            ->post($this->pagarmeUrl('/recipients'), [
+                'default_bank_account' => [
+                    'holder_name'         => $bankAccountData['holder_name'],
+                    'holder_type'         => $bankAccountData['holder_type'],
+                    'holder_document'     => $bankAccountData['holder_document'],
+                    'bank'                => $bankAccountData['bank'],
+                    'branch_number'       => $bankAccountData['branch_number'],
+                    'branch_check_digit'  => $bankAccountData['branch_check_digit'] ?? null,
+                    'account_number'      => $bankAccountData['account_number'],
+                    'account_check_digit' => $bankAccountData['account_check_digit'],
+                    'type'                => $bankAccountData['type'],
+                    'metadata'            => $bankAccountData['metadata'] ?? [],
+                    'pix_key'             => $bankAccountData['pix_key'] ?? null,
+                ],
+
+                'metadata'     => $metadata,
+                'code'         => $data['recipient_code'],
+                'payment_mode' => $paymentMode,
+                'name'         => $data['recipient_name'],
+                'email'        => $data['recipient_email'],
+                'description'  => $data['recipient_description'],
+                'document'     => $data['recipient_document'],
+                'type'         => $data['recipient_type'],
+
+                'transfer_settings' => [
+                    'transfer_enabled'  => false,
+                    'transfer_interval' => 'daily',
+                    'transfer_day'      => 0,
+                ],
+            ]);
+
+        if ($response->failed()) {
+            Log::channel('pagarme')->error('Pagar.me recipient creation failed', [
+                'status' => $response->status(),
+                'body'   => $response->json() ?? $response->body(),
+            ]);
+
+            throw new \RuntimeException('Erro ao criar recebedor no Pagar.me.');
+        }
+
+        $recipientData = $response->json();
+        $recipientId   = $recipientData['id'] ?? null;
+
         if (!$recipientId) {
+            Log::channel('pagarme')->error('Pagar.me recipient creation returned empty id', [
+                'response' => $recipientData,
+            ]);
+
             throw new \RuntimeException('Pagar.me recipient creation returned an empty id.');
         }
 
         $provider->forceFill([
-            'recipient_id' => $recipientId,
-            'recipient_name' => $data['recipient_name'],
-            'recipient_email' => $data['recipient_email'],
-            'recipient_description' => $data['recipient_description'],
-            'recipient_document' => $data['recipient_document'],
-            'recipient_type' => $data['recipient_type'],
-            'recipient_code' => $data['recipient_code'],
-            'recipient_payment_mode' => $paymentMode,
+            'recipient_id'                   => $recipientId,
+            'recipient_name'                 => $data['recipient_name'],
+            'recipient_email'                => $data['recipient_email'],
+            'recipient_description'          => $data['recipient_description'],
+            'recipient_document'             => $data['recipient_document'],
+            'recipient_type'                 => $data['recipient_type'],
+            'recipient_code'                 => $data['recipient_code'],
+            'recipient_payment_mode'         => $paymentMode,
             'recipient_default_bank_account' => $bankAccountData,
+
             'recipient_transfer_settings' => [
-                'transfer_enabled' => false,
+                'transfer_enabled'  => false,
                 'transfer_interval' => 'daily',
-                'transfer_day' => 0,
+                'transfer_day'      => 0,
             ],
+
             'recipient_automatic_anticipation_settings' => [
                 'enabled' => false,
             ],
+
             'recipient_metadata' => $metadata,
         ])->save();
 
@@ -93,44 +99,53 @@ class PagarmeRecipientService
         return $recipientId;
     }
 
-    private function applyAutomaticAnticipationSettings(int $providerId, string $recipientId): void
+    //
+
+    private function pagarmeUrl(string $path): string
     {
-        $request = UpdateAutomaticAnticipationSettingsRequestBuilder::init()
-            ->enabled(false)
-            ->build();
-
-        $this->client()->getRecipientsController()->updateAutomaticAnticipationSettings(
-            $recipientId,
-            $request,
-            $this->idempotencyKey($providerId, 'auto-anticipation')
-        );
+        return rtrim(config('services.pagarme.base_url'), '/') . '/' . ltrim($path, '/');
     }
 
-    private function client(): PagarmeApiSDKClient
+    private function idempotencyKey(int $providerId, string $suffix = 'recipient'): string
     {
-        if ($this->client) {
-            return $this->client;
-        }
+        return "provider-{$providerId}-{$suffix}";
+    }
 
+    //
+
+    private function pagarmeRequest(int $providerId, string $suffix = 'recipient')
+    {
         $secretKey = config('services.pagarme.secret_key');
+
         if (empty($secretKey)) {
+            Log::channel('pagarme')->error('PAGARME_SECRET_KEY is not configured.');
+
             throw new \RuntimeException('PAGARME_SECRET_KEY is not configured.');
         }
 
-        $serviceRefererName = (string) config('services.pagarme.service_referer_name', config('app.name'));
-
-        $this->client = PagarmeApiSDKClientBuilder::init()
-            ->basicAuthCredentials(
-                BasicAuthCredentialsBuilder::init($secretKey, '')
-            )
-            ->serviceRefererName($serviceRefererName)
-            ->build();
-
-        return $this->client;
+        return Http::withBasicAuth($secretKey, '')
+            ->withHeaders([
+                'Idempotency-Key' => $this->idempotencyKey($providerId, $suffix),
+                'Content-Type'    => 'application/json',
+                'Accept'          => 'application/json',
+            ]);
     }
 
-    private function idempotencyKey(int $providerId, string $suffix = 'recipient'): string
+    private function applyAutomaticAnticipationSettings(int $providerId, string $recipientId): void
     {
-        return "provider-{$providerId}-{$suffix}";
+        $response = $this->pagarmeRequest($providerId, 'auto-anticipation')
+            ->patch($this->pagarmeUrl("/recipients/{$recipientId}/automatic-anticipation-settings"), [
+                'enabled' => false,
+            ]);
+
+        if ($response->failed()) {
+            Log::channel('pagarme')->error('Pagar.me automatic anticipation settings update failed', [
+                'status'       => $response->status(),
+                'body'         => $response->json() ?? $response->body(),
+                'recipient_id' => $recipientId,
+            ]);
+
+            throw new \RuntimeException('Erro ao atualizar antecipação automática do recebedor no Pagar.me.');
+        }
     }
-}
+}

+ 46 - 37
config/logging.php

@@ -33,7 +33,7 @@ return [
 
     'deprecations' => [
         'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
-        'trace' => env('LOG_DEPRECATIONS_TRACE', false),
+        'trace'   => env('LOG_DEPRECATIONS_TRACE', false),
     ],
 
     /*
@@ -53,73 +53,76 @@ return [
     'channels' => [
 
         'stack' => [
-            'driver' => 'stack',
-            'channels' => explode(',', env('LOG_STACK', 'single')),
+            'driver'            => 'stack',
+            'channels'          => explode(',', env('LOG_STACK', 'single')),
             'ignore_exceptions' => false,
         ],
 
         'single' => [
-            'driver' => 'single',
-            'path' => storage_path('logs/laravel.log'),
-            'level' => env('LOG_LEVEL', 'debug'),
+            'driver'               => 'single',
+            'path'                 => storage_path('logs/laravel.log'),
+            'level'                => env('LOG_LEVEL', 'debug'),
             'replace_placeholders' => true,
         ],
 
         'daily' => [
-            'driver' => 'daily',
-            'path' => storage_path('logs/laravel.log'),
-            'level' => env('LOG_LEVEL', 'debug'),
-            'days' => env('LOG_DAILY_DAYS', 14),
+            'driver'               => 'daily',
+            'path'                 => storage_path('logs/laravel.log'),
+            'level'                => env('LOG_LEVEL', 'debug'),
+            'days'                 => env('LOG_DAILY_DAYS', 14),
             'replace_placeholders' => true,
         ],
 
         'slack' => [
-            'driver' => 'slack',
-            'url' => env('LOG_SLACK_WEBHOOK_URL'),
-            'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'),
-            'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),
-            'level' => env('LOG_LEVEL', 'critical'),
+            'driver'               => 'slack',
+            'url'                  => env('LOG_SLACK_WEBHOOK_URL'),
+            'username'             => env('LOG_SLACK_USERNAME', 'Laravel Log'),
+            'emoji'                => env('LOG_SLACK_EMOJI', ':boom:'),
+            'level'                => env('LOG_LEVEL', 'critical'),
             'replace_placeholders' => true,
         ],
 
         'papertrail' => [
-            'driver' => 'monolog',
-            'level' => env('LOG_LEVEL', 'debug'),
+            'driver'  => 'monolog',
+            'level'   => env('LOG_LEVEL', 'debug'),
             'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
+
             'handler_with' => [
-                'host' => env('PAPERTRAIL_URL'),
-                'port' => env('PAPERTRAIL_PORT'),
+                'host'             => env('PAPERTRAIL_URL'),
+                'port'             => env('PAPERTRAIL_PORT'),
                 'connectionString' => 'tls://' . env('PAPERTRAIL_URL') . ':' . env('PAPERTRAIL_PORT'),
             ],
             'processors' => [PsrLogMessageProcessor::class],
         ],
 
         'stderr' => [
-            'driver' => 'monolog',
-            'level' => env('LOG_LEVEL', 'debug'),
-            'handler' => StreamHandler::class,
+            'driver'    => 'monolog',
+            'level'     => env('LOG_LEVEL', 'debug'),
+            'handler'   => StreamHandler::class,
             'formatter' => env('LOG_STDERR_FORMATTER'),
+
             'with' => [
                 'stream' => 'php://stderr',
             ],
+
             'processors' => [PsrLogMessageProcessor::class],
         ],
 
         'syslog' => [
-            'driver' => 'syslog',
-            'level' => env('LOG_LEVEL', 'debug'),
-            'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER),
+            'driver'               => 'syslog',
+            'level'                => env('LOG_LEVEL', 'debug'),
+            'facility'             => env('LOG_SYSLOG_FACILITY', LOG_USER),
             'replace_placeholders' => true,
         ],
 
         'errorlog' => [
-            'driver' => 'errorlog',
-            'level' => env('LOG_LEVEL', 'debug'),
+            'driver'               => 'errorlog',
+            'level'                => env('LOG_LEVEL', 'debug'),
             'replace_placeholders' => true,
         ],
 
         'null' => [
-            'driver' => 'monolog',
+            'driver'  => 'monolog',
             'handler' => NullHandler::class,
         ],
 
@@ -129,23 +132,29 @@ return [
 
         'expiredTokens' => [
             'driver' => 'daily',
-            'path' => storage_path('logs/deleted/expired_tokens.log'),
+            'path'   => storage_path('logs/deleted/expired_tokens.log'),
             'level' => 'info',
-            'days' => 7,
+            'days'   => 7,
         ],
         'schedule_start_jobs' => [
             'driver' => 'daily',
-            'path' => storage_path('logs/schedules/start_jobs.log'),
-            'level' => 'info',
-            'days' => 7,
+            'path'   => storage_path('logs/schedules/start_jobs.log'),
+            'level'  => 'info',
+            'days'   => 7,
         ],
         'schedule_end_jobs' => [
             'driver' => 'daily',
-            'path' => storage_path('logs/schedules/end_jobs.log'),
-            'level' => 'info',
-            'days' => 7,
+            'path'   => storage_path('logs/schedules/end_jobs.log'),
+            'level'  => 'info',
+            'days'   => 7,
+        ],
+        'pagarme' => [
+            'driver'               => 'daily',
+            'path'                 => storage_path('logs/integrations/pagarme.log'),
+            'level'                => 'debug',
+            'days'                 => 14,
+            'replace_placeholders' => true,
         ],
-
     ],
 
 ];

+ 4 - 3
config/services.php

@@ -19,7 +19,7 @@ return [
     ],
 
     'ses' => [
-        'key' => env('AWS_ACCESS_KEY_ID'),
+        'key'    => env('AWS_ACCESS_KEY_ID'),
         'secret' => env('AWS_SECRET_ACCESS_KEY'),
         'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
     ],
@@ -31,13 +31,14 @@ return [
     'slack' => [
         'notifications' => [
             'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'),
-            'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
+            'channel'              => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
         ],
     ],
 
     'pagarme' => [
-        'secret_key' => env('PAGARME_SECRET_KEY'),
+        'secret_key'           => env('PAGARME_SECRET_KEY'),
         'service_referer_name' => env('PAGARME_SERVICE_REFERER_NAME', env('APP_NAME', 'Laravel')),
+        'base_url'             => env('PAGARME_BASE_URL', 'https://api.pagar.me/core/v5'),
     ],
 
 ];