PagarmeRecipientService.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. namespace App\Services\Pagarme;
  3. use App\Data\Pagarme\Recipient\BankAccountUpdateRequestData;
  4. use App\Data\Pagarme\Recipient\Parts\Request\AddressData;
  5. use App\Data\Pagarme\Recipient\Parts\Request\AutomaticAnticipationSettingsData;
  6. use App\Data\Pagarme\Recipient\Parts\Request\BankAccountData;
  7. use App\Data\Pagarme\Recipient\Parts\Request\PhoneData;
  8. use App\Data\Pagarme\Recipient\Parts\Request\PhoneNumbersData;
  9. use App\Data\Pagarme\Recipient\Parts\Request\RegisterInformationData;
  10. use App\Data\Pagarme\Recipient\Parts\Request\TransferSettingsData;
  11. use App\Data\Pagarme\Recipient\RecipientRequestData;
  12. use App\Data\Pagarme\Recipient\RecipientResponseData;
  13. use App\Models\Provider;
  14. use App\Services\Pagarme\Concerns\FormatsPagarmeData;
  15. use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
  16. class PagarmeRecipientService
  17. {
  18. use FormatsPagarmeData;
  19. use SendsPagarmeRequests;
  20. public function createRecipientForProvider(Provider $provider, array $data): string
  21. {
  22. if (! empty($provider->recipient_id)) {
  23. return $provider->recipient_id;
  24. }
  25. $metadata = $data['recipient_metadata'] ?? [];
  26. $paymentMode = $data['recipient_payment_mode'];
  27. $recipientCode = $provider->ensureGatewayCode();
  28. $addressParts = $this->extractAddressParts($data);
  29. $registerInformation = new RegisterInformationData(
  30. name: $data['recipient_name'],
  31. email: $data['recipient_email'],
  32. document: $this->digits($data['recipient_document'] ?? null),
  33. type: $data['recipient_type'] ?? 'individual',
  34. birthdate: $this->formatBirthdate($data['birth_date'] ?? null),
  35. monthlyIncome: isset($data['monthly_income']) ? (int) $data['monthly_income'] : 1000,
  36. professionalOccupation: $data['professional_occupation'] ?? 'autonomo',
  37. phoneNumbers: new PhoneNumbersData(
  38. $this->buildRecipientPhone($data['phone'] ?? null),
  39. ),
  40. address: new AddressData(
  41. street: $addressParts['street'],
  42. complementary: $addressParts['complementary'],
  43. streetNumber: $addressParts['street_number'],
  44. neighborhood: $addressParts['neighborhood'],
  45. city: $data['city'] ?? null,
  46. state: $data['state'] ?? null,
  47. zipCode: $this->digits($data['zip_code'] ?? null),
  48. referencePoint: $addressParts['reference_point'],
  49. ),
  50. );
  51. $defaultBankAccount = $this->buildRecipientBankAccount(
  52. $data['recipient_default_bank_account'],
  53. );
  54. $payload = new RecipientRequestData(
  55. code: $recipientCode,
  56. registerInformation: $registerInformation,
  57. defaultBankAccount: $defaultBankAccount,
  58. transferSettings: new TransferSettingsData(
  59. transferEnabled: false,
  60. transferInterval: 'Daily',
  61. transferDay: 0,
  62. ),
  63. automaticAnticipationSettings: new AutomaticAnticipationSettingsData(
  64. enabled: true,
  65. type: 'full',
  66. volumePercentage: 100,
  67. delay: 0,
  68. ),
  69. );
  70. $bankAccountData = $payload->defaultBankAccount->toArray();
  71. $raw = $this->pagarmeRequest(
  72. method: 'POST',
  73. path: '/recipients',
  74. payload: $payload,
  75. idempotencyKey: $this->idempotencyKey($provider),
  76. errorMessage: 'Erro ao criar recebedor no Pagar.me.',
  77. );
  78. $recipientData = RecipientResponseData::fromArray($raw);
  79. $recipientId = $recipientData->requireId();
  80. $provider->forceFill([
  81. 'recipient_id' => $recipientId,
  82. 'recipient_name' => $data['recipient_name'],
  83. 'recipient_email' => $data['recipient_email'],
  84. 'recipient_description' => $data['recipient_description'] ?? '',
  85. 'recipient_document' => $data['recipient_document'],
  86. 'recipient_type' => $payload->registerInformation->type,
  87. 'recipient_code' => $recipientCode,
  88. 'recipient_payment_mode' => $paymentMode,
  89. 'recipient_default_bank_account' => $bankAccountData,
  90. 'recipient_transfer_settings' => [
  91. 'transfer_enabled' => false,
  92. 'transfer_interval' => 'daily',
  93. 'transfer_day' => 0,
  94. ],
  95. 'recipient_automatic_anticipation_settings' => [
  96. 'enabled' => true,
  97. 'type' => 'full',
  98. 'volume_percentage' => 100,
  99. 'delay' => 0,
  100. ],
  101. 'recipient_metadata' => $metadata,
  102. ])->save();
  103. return $recipientId;
  104. }
  105. public function updateDefaultBankAccount(Provider $provider, array $bankAccountData): Provider
  106. {
  107. $payload = new BankAccountUpdateRequestData(
  108. holderName: $this->normalizeHolderName($bankAccountData['holder_name']),
  109. holderType: $bankAccountData['holder_type'],
  110. holderDocument: $this->digits($bankAccountData['holder_document']),
  111. bank: $bankAccountData['bank'],
  112. branchNumber: $bankAccountData['branch_number'],
  113. branchCheckDigit: $bankAccountData['branch_check_digit'] ?? null,
  114. accountNumber: $bankAccountData['account_number'],
  115. accountCheckDigit: $bankAccountData['account_check_digit'],
  116. type: $bankAccountData['type'],
  117. );
  118. $raw = $this->pagarmeRequest(
  119. method: 'PATCH',
  120. path: "/recipients/{$provider->recipient_id}/default-bank-account",
  121. payload: $payload,
  122. idempotencyKey: $this->idempotencyKey($provider, 'default-bank-account-'.sha1(json_encode($payload->toArray()))),
  123. errorMessage: 'Erro ao atualizar conta bancaria do recebedor no Pagar.me.',
  124. );
  125. $recipientData = RecipientResponseData::fromArray($raw);
  126. $provider->forceFill([
  127. 'recipient_default_bank_account' => $recipientData->defaultBankAccount?->toArray() ?: $payload->toArray()['bank_account'],
  128. ])->save();
  129. return $provider->fresh();
  130. }
  131. //
  132. private function buildRecipientBankAccount(array $data): BankAccountData
  133. {
  134. return new BankAccountData(
  135. holderName: $this->normalizeHolderName($data['holder_name']),
  136. holderType: $data['holder_type'],
  137. holderDocument: $this->digits($data['holder_document']),
  138. bank: $data['bank'],
  139. branchNumber: $data['branch_number'],
  140. branchCheckDigit: $data['branch_check_digit'] ?? null,
  141. accountNumber: $data['account_number'],
  142. accountCheckDigit: $data['account_check_digit'],
  143. type: $data['type'],
  144. );
  145. }
  146. private function buildRecipientPhone(?string $phone): PhoneData
  147. {
  148. $digits = $this->digits($phone);
  149. if (strlen($digits) < 10) {
  150. return new PhoneData(
  151. ddd: '11',
  152. number: '999999999',
  153. type: 'mobile',
  154. );
  155. }
  156. if (str_starts_with($digits, '55')) {
  157. $digits = substr($digits, 2);
  158. }
  159. return new PhoneData(
  160. ddd: substr($digits, 0, 2),
  161. number: substr($digits, 2),
  162. type: 'mobile',
  163. );
  164. }
  165. // evita criacao duplica de recipient
  166. private function idempotencyKey(Provider $provider, string $suffix = ''): string
  167. {
  168. $baseKey = $provider->idempotency_key;
  169. if (empty($baseKey)) {
  170. $baseKey = 'recipient-'.(string) \Illuminate\Support\Str::uuid();
  171. $provider->forceFill(['idempotency_key' => $baseKey])->save();
  172. }
  173. return $suffix ? "{$baseKey}-{$suffix}" : $baseKey;
  174. }
  175. }