provider()->first(); if (! $provider) { return null; } $recipientId = $provider->recipient_id; if (empty($recipientId)) { return null; } $providerSplit = $payment->splits() ->where('provider_id', $payment->provider_id) ->first(); if (! $providerSplit) { return null; } $requestedAmount = OrderRequestData::amountInCents((float) $providerSplit->gross_amount); if ($requestedAmount <= 0) { return null; } $paymentDate = $this->getAnticipationPaymentDate(); $limits ??= $this->fetchAnticipationLimits($recipientId, $paymentDate); if ($limits && $limits->maximum->amount <= 0) { Log::channel('pagarme')->warning('Antecipacao ignorada: recebedor sem valor disponivel para antecipar.', [ 'payment_id' => $payment->id, 'provider_id' => $payment->provider_id, 'recipient_id' => $recipientId, 'requested_amount' => $requestedAmount, 'minimum_amount' => $limits->minimum->amount, 'maximum_amount' => $limits->maximum->amount, ]); return null; } if ($limits && $limits->minimum->amount > 0 && $requestedAmount < $limits->minimum->amount) { Log::channel('pagarme')->warning('Antecipacao ignorada: valor abaixo do minimo do recebedor.', [ 'payment_id' => $payment->id, 'provider_id' => $payment->provider_id, 'recipient_id' => $recipientId, 'requested_amount' => $requestedAmount, 'minimum_amount' => $limits->minimum->amount, 'maximum_amount' => $limits->maximum->amount, ]); return null; } if ($limits && $limits->maximum->amount > 0 && $requestedAmount > $limits->maximum->amount) { Log::channel('pagarme')->warning('Antecipacao ignorada: valor acima do maximo disponivel do recebedor.', [ 'payment_id' => $payment->id, 'provider_id' => $payment->provider_id, 'recipient_id' => $recipientId, 'requested_amount' => $requestedAmount, 'minimum_amount' => $limits->minimum->amount, 'maximum_amount' => $limits->maximum->amount, ]); return null; } try { $response = BulkAnticipationResponseData::fromArray($this->pagarmeRequest( method: 'POST', path: "/recipients/{$recipientId}/bulk_anticipations", payload: new BulkAnticipationRequestData( paymentDate: $paymentDate, timeframe: 'start', requestedAmount: $requestedAmount, automaticTransfer: false, ), idempotencyKey: "bulk-ant-{$payment->id}-{$payment->provider_id}", errorMessage: 'Erro ao criar antecipacao no Pagar.me.', )); $response->requireId(); return $response; } catch (Throwable $e) { Log::channel('pagarme')->warning('Falha ao criar antecipacao no Pagar.me.', [ 'payment_id' => $payment->id, 'provider_id' => $payment->provider_id, 'recipient_id' => $recipientId, 'requested_amount' => $requestedAmount, 'minimum_amount' => $limits?->minimum->amount, 'maximum_amount' => $limits?->maximum->amount, 'error' => $e->getMessage(), ]); return null; } } public function fetchAnticipationLimitsForPayment(Payment $payment): ?BulkAnticipationLimitsResponseData { $provider = $payment->provider()->first(); if (! $provider || empty($provider->recipient_id)) { return null; } return $this->fetchAnticipationLimits( recipientId: $provider->recipient_id, paymentDate: $this->getAnticipationPaymentDate(), ); } private function fetchAnticipationLimits(string $recipientId, string $paymentDate): ?BulkAnticipationLimitsResponseData { try { $secretKey = config('services.pagarme.secret_key'); if (empty($secretKey)) { return null; } $endpoint = $this->pagarmeUrl("/recipients/{$recipientId}/bulk_anticipations/limits"); $response = Http::withBasicAuth($secretKey, '') ->withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json', ]) ->get($endpoint, [ 'payment_date' => $paymentDate, 'timeframe' => 'start', ]) ->throw(); $body = $response->json() ?? []; $limits = BulkAnticipationLimitsResponseData::fromArray($body); Log::channel('pagarme')->info('Limites de antecipacao consultados no Pagar.me.', [ 'recipient_id' => $recipientId, 'payment_date' => $paymentDate, 'minimum_amount' => $limits->minimum->amount, 'maximum_amount' => $limits->maximum->amount, ]); return $limits; } catch (Throwable $e) { Log::channel('pagarme')->warning('Falha ao consultar limites de antecipacao.', [ 'recipient_id' => $recipientId, 'payment_date' => $paymentDate, 'error' => $e->getMessage(), ]); return null; } } private function getAnticipationPaymentDate(): string { $now = now()->timezone('America/Sao_Paulo'); if ($now->hour < 11) { return $now->toISOString(); } $nextBusinessDay = $now->copy()->addDay(); while ($nextBusinessDay->isWeekend()) { $nextBusinessDay->addDay(); } return $nextBusinessDay->startOfDay()->toISOString(); } }