Przeglądaj źródła

feat: add condicoes para ambiente de teste para realizacao do saque

Gustavo Mantovani 2 tygodni temu
rodzic
commit
e231876bf3

+ 3 - 0
app/Data/Pagarme/Request/PagarmeBankAccountUpdateRequestData.php

@@ -60,6 +60,8 @@ final readonly class PagarmeBankAccountUpdateRequestData extends PagarmeData
         ]);
     }
 
+    //
+
     private static function normalizeHolderName(string $holderName): string
     {
         $holderName = trim(preg_replace('/\s+/', ' ', $holderName) ?? '');
@@ -72,6 +74,7 @@ final readonly class PagarmeBankAccountUpdateRequestData extends PagarmeData
 
         if (count($parts) >= 3) {
             $firstName = array_shift($parts);
+
             $lastName = array_pop($parts);
 
             $initials = array_map(

+ 21 - 21
app/Data/Pagarme/Request/PagarmeOrderRequestData/PagarmeOrderRequestData.php

@@ -91,6 +91,11 @@ final readonly class PagarmeOrderRequestData extends PagarmeData
 
     //
 
+    public static function amountInCents(float $amount): int
+    {
+        return (int) round($amount * 100);
+    }
+
     public static function creditCardPaymentMethod(array $creditCard, ?array $split = null): array
     {
         return self::paymentMethodWithOptionalSplit([
@@ -130,6 +135,22 @@ final readonly class PagarmeOrderRequestData extends PagarmeData
 
     //
 
+    public function toArray(): array
+    {
+        return $this->filterFilledRecursive([
+            'code'        => $this->code,
+            'items'       => $this->items,
+            'payments'    => $this->payments,
+            'closed'      => $this->closed,
+            'metadata'    => $this->metadata,
+            'customer_id' => $this->customerId,
+            'customer'    => $this->customer,
+            'channel'     => $this->channel,
+        ]);
+    }
+
+    //
+
     private static function buildCreditCardPayload(array $creditCard): array
     {
         $payload = [];
@@ -195,11 +216,6 @@ final readonly class PagarmeOrderRequestData extends PagarmeData
 
     //
 
-    public static function amountInCents(float $amount): int
-    {
-        return (int) round($amount * 100);
-    }
-
     private static function filled(mixed $value): bool
     {
         return $value !== null && $value !== '' && $value !== [];
@@ -250,20 +266,4 @@ final readonly class PagarmeOrderRequestData extends PagarmeData
             ->values()
             ->all();
     }
-
-    //
-
-    public function toArray(): array
-    {
-        return $this->filterFilledRecursive([
-            'code'        => $this->code,
-            'items'       => $this->items,
-            'payments'    => $this->payments,
-            'closed'      => $this->closed,
-            'metadata'    => $this->metadata,
-            'customer_id' => $this->customerId,
-            'customer'    => $this->customer,
-            'channel'     => $this->channel,
-        ]);
-    }
 }

+ 3 - 0
app/Data/Pagarme/Request/PagarmeRecipientRequestData/PagarmeRecipientBankAccountData.php

@@ -58,6 +58,8 @@ final readonly class PagarmeRecipientBankAccountData extends PagarmeData
         ]);
     }
 
+    //
+
     private static function normalizeHolderName(string $holderName): string
     {
         $holderName = trim(preg_replace('/\s+/', ' ', $holderName) ?? '');
@@ -70,6 +72,7 @@ final readonly class PagarmeRecipientBankAccountData extends PagarmeData
 
         if (count($parts) >= 3) {
             $firstName = array_shift($parts);
+
             $lastName = array_pop($parts);
 
             $initials = array_map(

+ 26 - 22
app/Data/Pagarme/Request/PagarmeRecipientRequestData/PagarmeRecipientRequestData.php

@@ -70,33 +70,14 @@ final readonly class PagarmeRecipientRequestData extends PagarmeData
         ]);
     }
 
-    private static function phoneFromPayload(?string $phone): PagarmeRecipientPhoneData
-    {
-        $digits = self::digits($phone);
-
-        if (strlen($digits) < 10) {
-            return new PagarmeRecipientPhoneData(
-                ddd: '11',
-                number: '999999999',
-                type: 'mobile',
-            );
-        }
-
-        if (str_starts_with($digits, '55')) {
-            $digits = substr($digits, 2);
-        }
-
-        return new PagarmeRecipientPhoneData(
-            ddd: substr($digits, 0, 2),
-            number: substr($digits, 2),
-            type: 'mobile',
-        );
-    }
+    //
 
     private static function extractAddressParts(array $data): array
     {
         $addressLine = trim((string) ($data['address'] ?? ''));
+
         $segments = array_map('trim', explode(',', $addressLine));
+
         $streetSegment = $segments[0] ?? '';
 
         if (($data['number'] ?? null) === null) {
@@ -133,4 +114,27 @@ final readonly class PagarmeRecipientRequestData extends PagarmeData
 
         return Carbon::parse($birthdate)->format('d/m/Y');
     }
+
+    private static function phoneFromPayload(?string $phone): PagarmeRecipientPhoneData
+    {
+        $digits = self::digits($phone);
+
+        if (strlen($digits) < 10) {
+            return new PagarmeRecipientPhoneData(
+                ddd: '11',
+                number: '999999999',
+                type: 'mobile',
+            );
+        }
+
+        if (str_starts_with($digits, '55')) {
+            $digits = substr($digits, 2);
+        }
+
+        return new PagarmeRecipientPhoneData(
+            ddd: substr($digits, 0, 2),
+            number: substr($digits, 2),
+            type: 'mobile',
+        );
+    }
 }

+ 22 - 20
app/Data/Pagarme/Response/PagarmeCardResponseData.php

@@ -18,21 +18,9 @@ final readonly class PagarmeCardResponseData
         public ?string $updatedAt = null,
     ) {}
 
-    public static function fromArray(array $payload): self
+    public function brand(): ?string
     {
-        return new self(
-            id: $payload['id'] ?? null,
-            firstSixDigits: $payload['first_six_digits'] ?? null,
-            lastFourDigits: $payload['last_four_digits'] ?? null,
-            brand: $payload['brand'] ?? null,
-            holderName: $payload['holder_name'] ?? null,
-            expMonth: isset($payload['exp_month']) ? (int) $payload['exp_month'] : null,
-            expYear: isset($payload['exp_year']) ? (int) $payload['exp_year'] : null,
-            status: $payload['status'] ?? null,
-            type: $payload['type'] ?? null,
-            createdAt: $payload['created_at'] ?? null,
-            updatedAt: $payload['updated_at'] ?? null,
-        );
+        return $this->brand;
     }
 
     public function id(): ?string
@@ -40,6 +28,11 @@ final readonly class PagarmeCardResponseData
         return $this->id;
     }
 
+    public function lastFourDigits(): ?string
+    {
+        return $this->lastFourDigits;
+    }
+
     public function requireId(): string
     {
         if (! $this->id) {
@@ -49,14 +42,23 @@ final readonly class PagarmeCardResponseData
         return $this->id;
     }
 
-    public function brand(): ?string
-    {
-        return $this->brand;
-    }
+    //
 
-    public function lastFourDigits(): ?string
+    public static function fromArray(array $payload): self
     {
-        return $this->lastFourDigits;
+        return new self(
+            id: $payload['id'] ?? null,
+            firstSixDigits: $payload['first_six_digits'] ?? null,
+            lastFourDigits: $payload['last_four_digits'] ?? null,
+            brand: $payload['brand'] ?? null,
+            holderName: $payload['holder_name'] ?? null,
+            expMonth: isset($payload['exp_month']) ? (int) $payload['exp_month'] : null,
+            expYear: isset($payload['exp_year']) ? (int) $payload['exp_year'] : null,
+            status: $payload['status'] ?? null,
+            type: $payload['type'] ?? null,
+            createdAt: $payload['created_at'] ?? null,
+            updatedAt: $payload['updated_at'] ?? null,
+        );
     }
 
     public function toArray(): array

+ 14 - 14
app/Data/Pagarme/Response/PagarmeCustomerResponseData/PagarmeCustomerResponseData.php

@@ -21,6 +21,20 @@ final readonly class PagarmeCustomerResponseData
         public ?string $updatedAt = null,
     ) {}
 
+    public function id(): ?string
+    {
+        return $this->id;
+    }
+
+    public function requireId(): string
+    {
+        if (! $this->id) {
+            throw new \RuntimeException('Customer creation returned an empty id.');
+        }
+
+        return $this->id;
+    }
+
     public static function fromArray(array $payload): self
     {
         return new self(
@@ -39,20 +53,6 @@ final readonly class PagarmeCustomerResponseData
         );
     }
 
-    public function id(): ?string
-    {
-        return $this->id;
-    }
-
-    public function requireId(): string
-    {
-        if (! $this->id) {
-            throw new \RuntimeException('Customer creation returned an empty id.');
-        }
-
-        return $this->id;
-    }
-
     public function toArray(): array
     {
         return [

+ 76 - 66
app/Data/Pagarme/Response/PagarmeOrderResponseData/PagarmeOrderResponseData.php

@@ -30,38 +30,50 @@ final readonly class PagarmeOrderResponseData
         public ?string $closedAt = null,
     ) {}
 
-    public static function fromArray(array $payload): self
+    public function authorizedAt(): ?string
     {
-        return new self(
-            id: $payload['id'] ?? null,
-            code: $payload['code'] ?? null,
-            amount: isset($payload['amount']) ? (int) $payload['amount'] : null,
-            currency: $payload['currency'] ?? null,
-            closed: $payload['closed'] ?? null,
-            status: $payload['status'] ?? null,
-            items: $payload['items'] ?? [],
-            customer: ! empty($payload['customer']) ? $payload['customer'] : null,
-            charges: $payload['charges'] ?? [],
-            checkouts: $payload['checkouts'] ?? [],
-            metadata: $payload['metadata'] ?? [],
-            createdAt: $payload['created_at'] ?? null,
-            updatedAt: $payload['updated_at'] ?? null,
-            closedAt: $payload['closed_at'] ?? null,
-        );
+        $transaction = $this->lastTransaction();
+
+        $transactionStatus = $transaction['status'] ?? null;
+
+        if (in_array($transactionStatus, ['authorized_pending_capture', 'captured', 'partial_capture'], true)) {
+            return $this->filledArrayValue($transaction, 'created_at');
+        }
+
+        return null;
     }
 
-    public function id(): ?string
+    public function failureCode(): ?string
     {
-        return $this->id;
+        return $this->filledArrayValue($this->lastTransaction()['gateway_response'] ?? [], 'code');
     }
 
-    public function requireId(): string
+    public function failureMessage(): ?string
     {
-        if (! $this->id) {
-            throw new \RuntimeException('Pagar.me order creation returned an empty id.');
+        $transaction = $this->lastTransaction();
+
+        $acquirerMessage = $this->filledArrayValue($transaction, 'acquirer_message');
+
+        if ($acquirerMessage) {
+            return $acquirerMessage;
         }
 
-        return $this->id;
+        $gatewayErrors = $transaction['gateway_response']['errors'] ?? [];
+
+        if (! is_array($gatewayErrors) || empty($gatewayErrors)) {
+            return null;
+        }
+
+        $message = collect($gatewayErrors)
+            ->pluck('message')
+            ->filter()
+            ->implode('; ') ?: null;
+
+        if ($message && str_contains($message, 'Sem ambiente configurado')) {
+            return 'Pix não esta habilitado ou configurado neste ambiente do Pagar.me.';
+        }
+
+        return $message;
     }
 
     public function firstCharge(): array
@@ -69,9 +81,9 @@ final readonly class PagarmeOrderResponseData
         return $this->charges[0] ?? [];
     }
 
-    public function lastTransaction(): array
+    public function gatewayEntityLabel(): string
     {
-        return $this->firstCharge()['last_transaction'] ?? [];
+        return isset($this->firstCharge()['id']) ? 'charge' : 'order';
     }
 
     public function gatewayEntityReference(): ?string
@@ -81,31 +93,40 @@ final readonly class PagarmeOrderResponseData
         return $charge['id'] ?? $this->id;
     }
 
-    public function gatewayEntityLabel(): string
+    public function gatewayOperationLabel(): string
     {
-        return isset($this->firstCharge()['id']) ? 'charge' : 'order';
+        $charge = $this->firstCharge();
+
+        $transaction = $this->lastTransaction();
+
+        return isset($transaction['id']) ? 'transaction' : (isset($charge['id']) ? 'charge' : 'order');
     }
 
     public function gatewayOperationReference(): ?string
     {
         $charge = $this->firstCharge();
+
         $transaction = $this->lastTransaction();
 
         return $transaction['id'] ?? $charge['id'] ?? $this->id;
     }
 
-    public function gatewayOperationLabel(): string
+    public function id(): ?string
     {
-        $charge = $this->firstCharge();
-        $transaction = $this->lastTransaction();
+        return $this->id;
+    }
 
-        return isset($transaction['id']) ? 'transaction' : (isset($charge['id']) ? 'charge' : 'order');
+    public function lastTransaction(): array
+    {
+        return $this->firstCharge()['last_transaction'] ?? [];
     }
 
     public function paymentStatus(): PaymentStatusEnum
     {
         $charge = $this->firstCharge();
+
         $transaction = $this->lastTransaction();
+
         $status = strtolower((string) (($transaction['status'] ?? null) ?: ($charge['status'] ?? null)));
 
         return match ($status) {
@@ -127,48 +148,35 @@ final readonly class PagarmeOrderResponseData
         return $this->filledArrayValue($this->firstCharge(), 'paid_at');
     }
 
-    public function authorizedAt(): ?string
+    public function requireId(): string
     {
-        $transaction = $this->lastTransaction();
-        $transactionStatus = $transaction['status'] ?? null;
-
-        if (in_array($transactionStatus, ['authorized_pending_capture', 'captured', 'partial_capture'], true)) {
-            return $this->filledArrayValue($transaction, 'created_at');
+        if (! $this->id) {
+            throw new \RuntimeException('Pagar.me order creation returned an empty id.');
         }
 
-        return null;
+        return $this->id;
     }
 
-    public function failureCode(): ?string
-    {
-        return $this->filledArrayValue($this->lastTransaction()['gateway_response'] ?? [], 'code');
-    }
+    //
 
-    public function failureMessage(): ?string
+    public static function fromArray(array $payload): self
     {
-        $transaction = $this->lastTransaction();
-        $acquirerMessage = $this->filledArrayValue($transaction, 'acquirer_message');
-
-        if ($acquirerMessage) {
-            return $acquirerMessage;
-        }
-
-        $gatewayErrors = $transaction['gateway_response']['errors'] ?? [];
-
-        if (! is_array($gatewayErrors) || empty($gatewayErrors)) {
-            return null;
-        }
-
-        $message = collect($gatewayErrors)
-            ->pluck('message')
-            ->filter()
-            ->implode('; ') ?: null;
-
-        if ($message && str_contains($message, 'Sem ambiente configurado')) {
-            return 'Pix não esta habilitado ou configurado neste ambiente do Pagar.me.';
-        }
-
-        return $message;
+        return new self(
+            id: $payload['id'] ?? null,
+            code: $payload['code'] ?? null,
+            amount: isset($payload['amount']) ? (int) $payload['amount'] : null,
+            currency: $payload['currency'] ?? null,
+            closed: $payload['closed'] ?? null,
+            status: $payload['status'] ?? null,
+            items: $payload['items'] ?? [],
+            customer: ! empty($payload['customer']) ? $payload['customer'] : null,
+            charges: $payload['charges'] ?? [],
+            checkouts: $payload['checkouts'] ?? [],
+            metadata: $payload['metadata'] ?? [],
+            createdAt: $payload['created_at'] ?? null,
+            updatedAt: $payload['updated_at'] ?? null,
+            closedAt: $payload['closed_at'] ?? null,
+        );
     }
 
     public function toArray(): array
@@ -191,6 +199,8 @@ final readonly class PagarmeOrderResponseData
         ];
     }
 
+    //
+
     private function filledArrayValue(array $data, string $field): ?string
     {
         if (! array_key_exists($field, $data) || $data[$field] === null || $data[$field] === '' || $data[$field] === []) {

+ 18 - 16
app/Data/Pagarme/Response/PagarmeRecipientResponseData/PagarmeRecipientResponseData.php

@@ -16,21 +16,9 @@ final readonly class PagarmeRecipientResponseData
         public ?string $updatedAt = null,
     ) {}
 
-    public static function fromArray(array $payload): self
+    public function defaultBankAccount(): ?PagarmeRecipientBankAccountResponseData
     {
-        return new self(
-            id: $payload['id'] ?? null,
-            name: $payload['name'] ?? null,
-            email: $payload['email'] ?? null,
-            document: $payload['document'] ?? null,
-            type: $payload['type'] ?? null,
-            status: $payload['status'] ?? null,
-            defaultBankAccount: ! empty($payload['default_bank_account'])
-                ? PagarmeRecipientBankAccountResponseData::fromArray($payload['default_bank_account'])
-                : null,
-            createdAt: $payload['created_at'] ?? null,
-            updatedAt: $payload['updated_at'] ?? null,
-        );
+        return $this->defaultBankAccount;
     }
 
     public function id(): ?string
@@ -47,9 +35,23 @@ final readonly class PagarmeRecipientResponseData
         return $this->id;
     }
 
-    public function defaultBankAccount(): ?PagarmeRecipientBankAccountResponseData
+    //
+
+    public static function fromArray(array $payload): self
     {
-        return $this->defaultBankAccount;
+        return new self(
+            id: $payload['id'] ?? null,
+            name: $payload['name'] ?? null,
+            email: $payload['email'] ?? null,
+            document: $payload['document'] ?? null,
+            type: $payload['type'] ?? null,
+            status: $payload['status'] ?? null,
+            defaultBankAccount: ! empty($payload['default_bank_account'])
+                ? PagarmeRecipientBankAccountResponseData::fromArray($payload['default_bank_account'])
+                : null,
+            createdAt: $payload['created_at'] ?? null,
+            updatedAt: $payload['updated_at'] ?? null,
+        );
     }
 
     public function toArray(): array

+ 12 - 10
app/Data/Pagarme/Response/PagarmeTransferResponseData.php

@@ -17,6 +17,18 @@ final readonly class PagarmeTransferResponseData
         public ?string $createdAt,
         public ?array $metadata,
     ) {}
+    
+    public function id(): ?string
+    {
+        return $this->id;
+    }
+
+    public function status(): ?string
+    {
+        return $this->status;
+    }
+
+    //
 
     public static function fromArray(array $payload): self
     {
@@ -35,16 +47,6 @@ final readonly class PagarmeTransferResponseData
         );
     }
 
-    public function id(): ?string
-    {
-        return $this->id;
-    }
-
-    public function status(): ?string
-    {
-        return $this->status;
-    }
-
     public function toArray(): array
     {
         return [

+ 32 - 0
app/Observers/ScheduleObserver.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Observers;
+
+use App\Models\Schedule;
+use Carbon\Carbon;
+
+class ScheduleObserver
+{
+    public function updated(Schedule $schedule): void
+    {
+        if (! $schedule->wasChanged('code_verified') || ! $schedule->code_verified) {
+            return;
+        }
+
+        if (in_array($schedule->status, ['finished', 'cancelled', 'rejected'], true)) {
+            return;
+        }
+
+        $endedAt = Carbon::parse($schedule->date->format('Y-m-d').' '.$schedule->end_time);
+
+        // if ($endedAt->isFuture()) {
+        //    return;
+        // }
+
+        $schedule->forceFill(['status' => 'finished'])->saveQuietly();
+
+        $schedule->provider?->increment('total_services');
+
+        $schedule->client?->increment('total_services');
+    }
+}

+ 5 - 1
app/Providers/AppServiceProvider.php

@@ -2,6 +2,8 @@
 
 namespace App\Providers;
 
+use App\Models\Schedule;
+use App\Observers\ScheduleObserver;
 use Illuminate\Support\ServiceProvider;
 
 class AppServiceProvider extends ServiceProvider
@@ -28,6 +30,8 @@ class AppServiceProvider extends ServiceProvider
      */
     public function boot(): void
     {
-        //
+        if ($this->app->environment(['local', 'development', 'dev'])) {
+            Schedule::observe(ScheduleObserver::class);
+        }
     }
 }

+ 1 - 1
app/Services/Pagarme/PagarmeCardService.php

@@ -63,7 +63,7 @@ class PagarmeCardService
         return $cardId;
     }
 
-    // evita criacao duplicada de cartao em retries/reprocessamentos
+    // evita criacao duplicada de cartao
 
     private function idempotencyKey(ClientPaymentMethod $paymentMethod): string
     {

+ 1 - 1
app/Services/Pagarme/PagarmePaymentService.php

@@ -91,7 +91,7 @@ class PagarmePaymentService
         return $order->toArray();
     }
 
-    // evita criacao duplicada de pedidos para o mesmo pagamento
+    // evita criacao duplicada de pedidos
 
     private function idempotencyKey(Payment $payment): string
     {

+ 1 - 1
app/Services/Pagarme/PagarmeRecipientService.php

@@ -81,7 +81,7 @@ class PagarmeRecipientService
         return $provider->fresh();
     }
 
-    //
+    // evita criacao duplica de recipient
 
     private function idempotencyKey(int $providerId, string $suffix = 'recipient'): string
     {

+ 3 - 1
app/Services/ProviderWithdrawalService.php

@@ -239,6 +239,8 @@ class ProviderWithdrawalService
 
     private function withdrawalReleaseCutoff(): string
     {
-        return Carbon::now()->subDays(5)->format('Y-m-d H:i:s');
+        return app()->environment('local', 'development')
+            ? Carbon::now()->format('Y-m-d H:i:s')
+            : Carbon::now()->subDays(5)->format('Y-m-d H:i:s');
     }
 }

+ 2 - 2
routes/authRoutes/provider.php

@@ -4,14 +4,14 @@ use App\Http\Controllers\ProviderController;
 use App\Http\Controllers\ProviderWithdrawalController;
 use Illuminate\Support\Facades\Route;
 
-Route::get('/provider/pending',                  [ProviderController::class, 'pending'])->middleware('permission:config.provider,view');
+Route::get('/provider/pending',                   [ProviderController::class, 'pending'])->middleware('permission:config.provider,view');
 Route::patch('/provider/{id}/approve',            [ProviderController::class, 'approve'])->middleware('permission:config.provider,edit');
 Route::patch('/provider/{id}/reject',             [ProviderController::class, 'reject'])->middleware('permission:config.provider,edit');
 Route::get('/provider/payment-splits',            [ProviderWithdrawalController::class, 'splits'])->middleware('permission:config.provider,view');
 Route::get('/provider/withdrawals/balance',       [ProviderWithdrawalController::class, 'balance'])->middleware('permission:config.provider,view');
 Route::get('/provider/withdrawals',               [ProviderWithdrawalController::class, 'index'])->middleware('permission:config.provider,view');
 Route::post('/provider/withdrawals',              [ProviderWithdrawalController::class, 'store'])->middleware('permission:config.provider,edit');
-Route::get('/provider/withdrawals/{id}',  [ProviderWithdrawalController::class, 'show'])->middleware('permission:config.provider,view');
+Route::get('/provider/withdrawals/{id}',          [ProviderWithdrawalController::class, 'show'])->middleware('permission:config.provider,view');
 Route::get('/provider',                           [ProviderController::class, 'index'])->middleware('permission:config.provider,view');
 Route::post('/provider',                          [ProviderController::class, 'store'])->middleware('permission:config.provider,add');
 Route::get('/provider/{id}',                      [ProviderController::class, 'show'])->middleware('permission:config.provider,view');