PagarmeCustomerService.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. namespace App\Services\Pagarme;
  3. use App\Data\Pagarme\Request\PagarmeCustomerRequestData\PagarmeCustomerAddressRequestData;
  4. use App\Data\Pagarme\Request\PagarmeCustomerRequestData\PagarmeCustomerPhonesRequestData\PagarmeCustomerPhoneData;
  5. use App\Data\Pagarme\Request\PagarmeCustomerRequestData\PagarmeCustomerPhonesRequestData\PagarmeCustomerPhonesRequestData;
  6. use App\Data\Pagarme\Request\PagarmeCustomerRequestData\PagarmeCustomerRequestData;
  7. use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerResponseData;
  8. use App\Models\Client;
  9. use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
  10. use Illuminate\Support\Str;
  11. class PagarmeCustomerService
  12. {
  13. use SendsPagarmeRequests;
  14. public function createCustomerForClient(Client $client, array $data): ?string
  15. {
  16. if (! empty($client->external_customer_id)) {
  17. return $client->external_customer_id;
  18. }
  19. $client->loadMissing('user');
  20. $name = $client->user?->name ?? $data['name'] ?? 'Cliente';
  21. $email = $client->user?->email ?? $data['email'] ?? null;
  22. $code = $this->ensureCustomerCode($client);
  23. $document = $this->onlyDigits($client->document ?? $data['document'] ?? null);
  24. $documentLen = strlen($document);
  25. $address = $this->buildAddressData($data);
  26. $phones = $this->buildPhones($client->user?->phone ?? $data['phone'] ?? null);
  27. $customerRequest = new PagarmeCustomerRequestData(
  28. name: $name,
  29. email: (string) $email,
  30. document: $document,
  31. type: $documentLen === 14 ? 'company' : 'individual',
  32. documentType: $documentLen === 14 ? 'CNPJ' : 'CPF',
  33. code: $code,
  34. address: $address,
  35. phones: $phones,
  36. );
  37. $customerData = PagarmeCustomerResponseData::fromArray($this->pagarmeRequest(
  38. method: 'POST',
  39. path: '/customers',
  40. payload: $customerRequest,
  41. idempotencyKey: $this->idempotencyKey($client->id),
  42. errorMessage: 'Erro ao criar cliente no Pagar.me.',
  43. ));
  44. $customerId = $customerData->requireId();
  45. $client->forceFill([
  46. 'external_customer_id' => $customerId,
  47. 'external_customer_code' => $code,
  48. ])->save();
  49. return $customerId;
  50. }
  51. //
  52. private function buildAddressData(array $data): PagarmeCustomerAddressRequestData
  53. {
  54. $line1Parts = array_filter([
  55. (string) ($data['number'] ?? '0'),
  56. (string) ($data['address'] ?? ''),
  57. (string) ($data['district'] ?? ''),
  58. ], static fn ($value) => $value !== '');
  59. return new PagarmeCustomerAddressRequestData(
  60. line1: implode(', ', $line1Parts),
  61. line2: (string) ($data['complement'] ?? $data['instructions'] ?? ''),
  62. zipCode: $this->onlyDigits($data['zip_code'] ?? null),
  63. city: (string) ($data['city'] ?? ''),
  64. state: (string) ($data['state'] ?? ''),
  65. country: (string) ($data['country'] ?? 'BR'),
  66. );
  67. }
  68. private function buildPhones(?string $phone): PagarmeCustomerPhonesRequestData
  69. {
  70. $digits = $this->onlyDigits($phone);
  71. if ($digits === '') {
  72. return new PagarmeCustomerPhonesRequestData;
  73. }
  74. $areaCode = substr($digits, 0, 2);
  75. $number = substr($digits, 2);
  76. if (strlen($digits) <= 2) {
  77. $areaCode = '';
  78. $number = $digits;
  79. }
  80. return new PagarmeCustomerPhonesRequestData(
  81. mobilePhone: new PagarmeCustomerPhoneData(
  82. countryCode: '55',
  83. areaCode: $areaCode,
  84. number: $number,
  85. ),
  86. );
  87. }
  88. private function onlyDigits(?string $value): string
  89. {
  90. return preg_replace('/\D+/', '', (string) $value) ?? '';
  91. }
  92. // evita criacao duplicada de customer
  93. private function idempotencyKey(int $clientId, string $suffix = 'customer'): string
  94. {
  95. return "client-{$clientId}-{$suffix}";
  96. }
  97. private function ensureCustomerCode(Client $client): string
  98. {
  99. if (! empty($client->external_customer_code)) {
  100. return $client->external_customer_code;
  101. }
  102. $code = 'client-'.(string) Str::uuid();
  103. $client->forceFill(['external_customer_code' => $code])->save();
  104. return $code;
  105. }
  106. }