external_customer_id)) { return $client->external_customer_id; } $client->loadMissing('user'); $name = $client->user?->name ?? $data['name'] ?? 'Cliente'; $email = $client->user?->email ?? $data['email'] ?? null; $document = $this->sanitizeDigits($client->document ?? $data['document'] ?? null); if (empty($email) || empty($document)) { Log::warning('Skipping customer creation because the client is missing email or document.', [ 'client_id' => $client->id, 'user_id' => $client->user_id, ]); return null; } $address = $this->buildAddress($data); $phones = $this->buildPhones($client->user?->phone ?? $data['phone'] ?? null); $code = $client->external_customer_code ?? "client-{$client->id}"; $customerRequest = CreateCustomerRequestBuilder::init( $name, $email, $document, $this->personType($document), $address, [ 'client_id' => (string) $client->id, 'user_id' => (string) ($client->user_id ?? ''), ], $phones, $code ) ->documentType($this->documentType($document)) ->build(); $customer = $this->client()->getCustomersController()->createCustomer( $customerRequest, $this->idempotencyKey($client->id) ); $customerId = $customer->getId(); if (!$customerId) { throw new \RuntimeException('Customer creation returned an empty id.'); } $client->forceFill([ 'external_customer_id' => $customerId, 'external_customer_code' => $code, ])->save(); return $customerId; } private function buildAddress(array $data): CreateAddressRequest { $zipCode = $this->sanitizeDigits($data['zip_code'] ?? null); $street = (string) ($data['address'] ?? ''); $number = (string) ($data['number'] ?? '0'); $neighborhood = (string) ($data['district'] ?? ''); $city = (string) ($data['city'] ?? ''); $state = (string) ($data['state'] ?? ''); $country = (string) ($data['country'] ?? 'BR'); $complement = (string) ($data['complement'] ?? ''); $line1Parts = array_filter([$number, $street, $neighborhood], static fn ($value) => $value !== ''); $line1 = implode(', ', $line1Parts); $line2 = $complement ?: (string) ($data['instructions'] ?? ''); return CreateAddressRequestBuilder::init( $street, $number, $zipCode, $neighborhood, $city, $state, $country, $complement, $line1, $line2 ) ->metadata([ 'source' => 'register-client', ]) ->build(); } private function buildPhones(?string $phone): CreatePhonesRequest { $digits = $this->sanitizeDigits($phone); $phonesBuilder = CreatePhonesRequestBuilder::init(); if (empty($digits)) { return $phonesBuilder->build(); } $countryCode = '55'; $areaCode = substr($digits, 0, 2); $number = substr($digits, 2); if (strlen($digits) <= 2) { $areaCode = ''; $number = $digits; } $mobilePhone = CreatePhoneRequestBuilder::init() ->countryCode($countryCode) ->areaCode($areaCode) ->number($number) ->type('mobile') ->build(); return $phonesBuilder ->mobilePhone($mobilePhone) ->build(); } private function documentType(string $document): string { return strlen($document) === 14 ? 'CNPJ' : 'CPF'; } private function personType(string $document): string { return strlen($document) === 14 ? 'company' : 'individual'; } private function sanitizeDigits(?string $value): string { return preg_replace('/\D+/', '', (string) $value) ?? ''; } private function client(): PagarmeApiSDKClient { if ($this->client) { return $this->client; } $secretKey = config('services.pagarme.secret_key'); if (empty($secretKey)) { throw new \RuntimeException('PAGARME_SECRET_KEY is not configured.'); } $serviceRefererName = (string) config('services.pagarme.service_referer_name', config('app.name')); $this->client = PagarmeApiSDKClientBuilder::init() ->basicAuthCredentials( BasicAuthCredentialsBuilder::init($secretKey, '') ) ->serviceRefererName($serviceRefererName) ->build(); return $this->client; } private function idempotencyKey(int $clientId): string { return "client-{$clientId}-customer"; } }