|
|
@@ -0,0 +1,185 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Services\Pagarme;
|
|
|
+
|
|
|
+use App\Models\Client;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+use PagarmeApiSDKLib\Authentication\BasicAuthCredentialsBuilder;
|
|
|
+use PagarmeApiSDKLib\Models\CreateAddressRequest;
|
|
|
+use PagarmeApiSDKLib\Models\CreatePhonesRequest;
|
|
|
+use PagarmeApiSDKLib\Models\Builders\CreateAddressRequestBuilder;
|
|
|
+use PagarmeApiSDKLib\Models\Builders\CreateCustomerRequestBuilder;
|
|
|
+use PagarmeApiSDKLib\Models\Builders\CreatePhoneRequestBuilder;
|
|
|
+use PagarmeApiSDKLib\Models\Builders\CreatePhonesRequestBuilder;
|
|
|
+use PagarmeApiSDKLib\PagarmeApiSDKClient;
|
|
|
+use PagarmeApiSDKLib\PagarmeApiSDKClientBuilder;
|
|
|
+
|
|
|
+class PagarmeCustomerService
|
|
|
+{
|
|
|
+ private ?PagarmeApiSDKClient $client = null;
|
|
|
+
|
|
|
+ public function createCustomerForClient(Client $client, array $data): ?string
|
|
|
+ {
|
|
|
+ if (!empty($client->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";
|
|
|
+ }
|
|
|
+}
|