PagarmeCustomerService.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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\PagarmeCustomerAddressResponseData;
  8. use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerPhonesResponseData\PagarmeCustomerPhonesResponseData;
  9. use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerPhonesResponseData\PagarmePhoneResponseData;
  10. use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerResponseData;
  11. use App\Models\Client;
  12. use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
  13. use Illuminate\Support\Str;
  14. class PagarmeCustomerService
  15. {
  16. use SendsPagarmeRequests;
  17. public function createCustomerForClient(Client $client, array $data): ?string
  18. {
  19. if (! empty($client->external_customer_id)) {
  20. return $client->external_customer_id;
  21. }
  22. $client->loadMissing('user');
  23. $name = $client->user?->name ?? $data['name'] ?? 'Cliente';
  24. $email = $client->user?->email ?? $data['email'] ?? null;
  25. $code = $this->ensureCustomerCode($client);
  26. $document = $this->onlyDigits($client->document ?? $data['document'] ?? null);
  27. $documentLen = strlen($document);
  28. $address = $this->buildAddressData($data);
  29. $phones = $this->buildPhones($client->user?->phone ?? $data['phone'] ?? null);
  30. $customerRequest = new PagarmeCustomerRequestData(
  31. name: $name,
  32. email: (string) $email,
  33. document: $document,
  34. type: $documentLen === 14 ? 'company' : 'individual',
  35. documentType: $documentLen === 14 ? 'CNPJ' : 'CPF',
  36. code: $code,
  37. address: $address,
  38. phones: $phones,
  39. );
  40. $raw = $this->pagarmeRequest(
  41. method: 'POST',
  42. path: '/customers',
  43. payload: $customerRequest,
  44. idempotencyKey: $this->idempotencyKey($client->id),
  45. errorMessage: 'Erro ao criar cliente no Pagar.me.',
  46. );
  47. $customerData = $this->buildCustomerResponse($raw);
  48. $customerId = $customerData->requireId();
  49. $client->forceFill([
  50. 'external_customer_id' => $customerId,
  51. 'external_customer_code' => $code,
  52. ])->save();
  53. return $customerId;
  54. }
  55. //
  56. private function buildAddressData(array $data): PagarmeCustomerAddressRequestData
  57. {
  58. $line1Parts = array_filter([
  59. (string) ($data['number'] ?? '0'),
  60. (string) ($data['address'] ?? ''),
  61. (string) ($data['district'] ?? ''),
  62. ], static fn ($value) => $value !== '');
  63. return new PagarmeCustomerAddressRequestData(
  64. line1: implode(', ', $line1Parts),
  65. line2: (string) ($data['complement'] ?? $data['instructions'] ?? ''),
  66. zipCode: $this->onlyDigits($data['zip_code'] ?? null),
  67. city: (string) ($data['city'] ?? ''),
  68. state: (string) ($data['state'] ?? ''),
  69. country: (string) ($data['country'] ?? 'BR'),
  70. );
  71. }
  72. private function buildPhones(?string $phone): PagarmeCustomerPhonesRequestData
  73. {
  74. $digits = $this->onlyDigits($phone);
  75. if ($digits === '') {
  76. return new PagarmeCustomerPhonesRequestData;
  77. }
  78. $areaCode = substr($digits, 0, 2);
  79. $number = substr($digits, 2);
  80. if (strlen($digits) <= 2) {
  81. $areaCode = '';
  82. $number = $digits;
  83. }
  84. return new PagarmeCustomerPhonesRequestData(
  85. mobilePhone: new PagarmeCustomerPhoneData(
  86. countryCode: '55',
  87. areaCode: $areaCode,
  88. number: $number,
  89. ),
  90. );
  91. }
  92. private function buildCustomerResponse(array $raw): PagarmeCustomerResponseData
  93. {
  94. return new PagarmeCustomerResponseData(
  95. id: $raw['id'] ?? null,
  96. name: $raw['name'] ?? null,
  97. email: $raw['email'] ?? null,
  98. code: $raw['code'] ?? null,
  99. document: $raw['document'] ?? null,
  100. documentType: $raw['document_type'] ?? null,
  101. type: $raw['type'] ?? null,
  102. delinquent: $raw['delinquent'] ?? null,
  103. address: ! empty($raw['address'])
  104. ? new PagarmeCustomerAddressResponseData(
  105. id: $raw['address']['id'] ?? null,
  106. line1: $raw['address']['line_1'] ?? null,
  107. line2: $raw['address']['line_2'] ?? null,
  108. zipCode: $raw['address']['zip_code'] ?? null,
  109. city: $raw['address']['city'] ?? null,
  110. state: $raw['address']['state'] ?? null,
  111. country: $raw['address']['country'] ?? null,
  112. status: $raw['address']['status'] ?? null,
  113. createdAt: $raw['address']['created_at'] ?? null,
  114. updatedAt: $raw['address']['updated_at'] ?? null,
  115. )
  116. : null,
  117. phones: new PagarmeCustomerPhonesResponseData(
  118. homePhone: ! empty($raw['phones']['home_phone'])
  119. ? new PagarmePhoneResponseData(
  120. countryCode: $raw['phones']['home_phone']['country_code'] ?? null,
  121. areaCode: $raw['phones']['home_phone']['area_code'] ?? null,
  122. number: $raw['phones']['home_phone']['number'] ?? null,
  123. )
  124. : null,
  125. mobilePhone: ! empty($raw['phones']['mobile_phone'])
  126. ? new PagarmePhoneResponseData(
  127. countryCode: $raw['phones']['mobile_phone']['country_code'] ?? null,
  128. areaCode: $raw['phones']['mobile_phone']['area_code'] ?? null,
  129. number: $raw['phones']['mobile_phone']['number'] ?? null,
  130. )
  131. : null,
  132. ),
  133. createdAt: $raw['created_at'] ?? null,
  134. updatedAt: $raw['updated_at'] ?? null,
  135. );
  136. }
  137. private function onlyDigits(?string $value): string
  138. {
  139. return preg_replace('/\D+/', '', (string) $value) ?? '';
  140. }
  141. // evita criacao duplicada de customer
  142. private function idempotencyKey(int $clientId, string $suffix = 'customer'): string
  143. {
  144. return "client-{$clientId}-{$suffix}";
  145. }
  146. private function ensureCustomerCode(Client $client): string
  147. {
  148. if (! empty($client->external_customer_code)) {
  149. return $client->external_customer_code;
  150. }
  151. $code = 'client-'.(string) Str::uuid();
  152. $client->forceFill(['external_customer_code' => $code])->save();
  153. return $code;
  154. }
  155. }