| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- <?php
- namespace App\Services\Pagarme;
- use App\Data\Pagarme\Anticipation\AnticipationLimitData;
- use App\Data\Pagarme\Anticipation\BulkAnticipationLimitsResponseData;
- use App\Data\Pagarme\Anticipation\BulkAnticipationRequestData;
- use App\Data\Pagarme\Anticipation\BulkAnticipationResponseData;
- use App\Data\Pagarme\Order\OrderRequestData;
- use App\Models\Payment;
- use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Support\Facades\Log;
- use Throwable;
- class PagarmeAnticipationService
- {
- use SendsPagarmeRequests;
- public function createBulkAnticipation(
- Payment $payment,
- ?BulkAnticipationLimitsResponseData $limits = null,
- ): ?BulkAnticipationResponseData
- {
- $provider = $payment->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();
- }
- }
|