PagarmeTransferService.php 4.9 KB

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