PagarmeTransferService.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <?php
  2. namespace App\Services\Pagarme;
  3. use App\Data\Pagarme\Transfer\TransferRequestData;
  4. use App\Data\Pagarme\Transfer\TransferResponseData;
  5. use App\Models\Provider;
  6. use App\Models\ProviderWithdrawal;
  7. use App\Services\Pagarme\Concerns\MocksPagarmeRequests;
  8. use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
  9. use Carbon\Carbon;
  10. class PagarmeTransferService
  11. {
  12. use MocksPagarmeRequests;
  13. use SendsPagarmeRequests;
  14. public function createTransfer(int $amountInCents, string $recipientId, string $idempotencyKey): TransferResponseData
  15. {
  16. if ($this->shouldMockTransferRequest()) {
  17. return $this->mockTransferResponse(
  18. amountInCents: $amountInCents,
  19. recipientId: $recipientId,
  20. idempotencyKey: $idempotencyKey,
  21. );
  22. }
  23. return TransferResponseData::fromArray($this->pagarmeRequest(
  24. method: 'POST',
  25. path: '/transfers',
  26. payload: new TransferRequestData(
  27. amount: $amountInCents,
  28. recipientId: $recipientId,
  29. ),
  30. idempotencyKey: $idempotencyKey,
  31. errorMessage: 'Erro ao criar transferencia (saque) no Pagar.me.',
  32. ));
  33. }
  34. public function getTransfer(string $transferId): TransferResponseData
  35. {
  36. if ($this->shouldMockTransferRequest()) {
  37. return $this->mockTransferLookupResponse($transferId);
  38. }
  39. return TransferResponseData::fromArray($this->pagarmeRequest(
  40. method: 'GET',
  41. path: "/transfers/{$transferId}",
  42. payload: [],
  43. idempotencyKey: "get-transfer-{$transferId}",
  44. errorMessage: 'Erro ao consultar transferencia no Pagar.me.',
  45. ));
  46. }
  47. //
  48. public function getRecipientBalance(string $recipientId): array
  49. {
  50. if ($this->shouldMockPagarmeRequest()) {
  51. return [
  52. 'recipient_id' => $recipientId,
  53. 'available' => ['amount' => 100000],
  54. 'waiting_funds'=> ['amount' => 0],
  55. 'transferred' => ['amount' => 0],
  56. 'mocked' => true,
  57. ];
  58. }
  59. return $this->pagarmeRequest(
  60. method: 'GET',
  61. path: "/recipients/{$recipientId}/balance",
  62. payload: [],
  63. idempotencyKey: "get-recipient-balance-{$recipientId}",
  64. errorMessage: 'Erro ao consultar saldo do recebedor no Pagar.me.',
  65. );
  66. }
  67. //
  68. private function mockTransferId(string $idempotencyKey): string
  69. {
  70. return $this->mockPagarmeId('tr', $idempotencyKey);
  71. }
  72. private function shouldMockTransferRequest(): bool
  73. {
  74. return $this->shouldMockPagarmeRequest();
  75. }
  76. //
  77. private function mockTransferLookupResponse(string $transferId): TransferResponseData
  78. {
  79. $withdrawal = ProviderWithdrawal::query()->where('transfer_id', $transferId)->first();
  80. if ($withdrawal?->gateway_payload) {
  81. return TransferResponseData::fromArray($withdrawal->gateway_payload);
  82. }
  83. $createdAt = Carbon::now();
  84. return new TransferResponseData(
  85. id: $transferId,
  86. amount: $withdrawal ? (int) round((float) $withdrawal->gross_amount * 100) : 0,
  87. type: $withdrawal?->type ?? 'credito_em_conta',
  88. status: $withdrawal?->status?->value ?? 'pending_transfer',
  89. fee: $withdrawal ? (int) round((float) $withdrawal->gateway_fee_amount * 100) : 0,
  90. fundingDate: $withdrawal?->completed_at?->toISOString(),
  91. fundingEstimatedDate: $createdAt->copy()->addWeekday()->toISOString(),
  92. bankAccount: $withdrawal?->bank_account,
  93. bankResponse: $withdrawal?->bank_response,
  94. createdAt: $withdrawal?->created_at?->toISOString() ?? $createdAt->toISOString(),
  95. metadata: $withdrawal?->metadata ?? [
  96. 'mocked' => true,
  97. 'environment' => app()->environment(),
  98. ],
  99. );
  100. }
  101. private function mockTransferResponse(int $amountInCents, string $recipientId, string $idempotencyKey): TransferResponseData
  102. {
  103. $provider = Provider::query()->where('recipient_id', $recipientId)->first();
  104. $createdAt = Carbon::now();
  105. return new TransferResponseData(
  106. id: $this->mockTransferId($idempotencyKey),
  107. amount: $amountInCents,
  108. type: 'credito_em_conta',
  109. status: 'pending_transfer',
  110. fee: 0,
  111. fundingDate: null,
  112. fundingEstimatedDate: $createdAt->copy()->addWeekday()->toISOString(),
  113. bankAccount: $provider?->recipient_default_bank_account,
  114. bankResponse: null,
  115. createdAt: $createdAt->toISOString(),
  116. metadata: [
  117. 'mocked' => true,
  118. 'environment' => app()->environment(),
  119. 'recipient_id' => $recipientId,
  120. 'idempotency_key' => $idempotencyKey,
  121. 'provider_id' => $provider?->id,
  122. ],
  123. );
  124. }
  125. }