| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- <?php
- namespace App\Services\Pagarme;
- use App\Models\Provider;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Support\Facades\Log;
- class PagarmeRecipientService
- {
- public function createRecipientForProvider(Provider $provider, array $data): string
- {
- if (! empty($provider->recipient_id)) {
- return $provider->recipient_id;
- }
- $bankAccountData = $data['recipient_default_bank_account'];
- $metadata = $data['recipient_metadata'] ?? [];
- $paymentMode = $data['recipient_payment_mode'];
- $recipientType = $data['recipient_type'] ?? 'individual';
- $addressParts = $this->extractAddressParts($data);
- $monthlyIncome = isset($data['monthly_income']) ? (int) $data['monthly_income'] : 1000;
- $occupation = $data['professional_occupation'] ?? 'autonomo';
- $payload = $this->filterFilledRecursive([
- 'code' => preg_replace('/\D+/', '', $data['recipient_code']),
- 'register_information' => [
- 'name' => $data['recipient_name'],
- 'email' => $data['recipient_email'],
- 'document' => preg_replace('/\D+/', '', $data['recipient_document']),
- 'type' => $recipientType,
- 'birthdate' => $data['birth_date'] ?? null,
- 'monthly_income' => $monthlyIncome,
- 'professional_occupation' => $occupation,
- 'phone_numbers' => $this->buildPhoneNumbers($data['phone'] ?? null),
- 'address' => [
- 'street' => $data['address'],
- 'complementary' => $addressParts['complementary'],
- 'street_number' => $addressParts['street_number'],
- 'neighborhood' => $addressParts['neighborhood'],
- 'city' => $data['city'] ?? null,
- 'state' => $data['state'] ?? null,
- 'zip_code' => preg_replace('/\D+/', '', $data['zip_code']),
- 'reference_point' => $addressParts['reference_point'],
- ],
- ],
- 'default_bank_account' => [
- 'holder_name' => $bankAccountData['holder_name'],
- 'holder_type' => $bankAccountData['holder_type'],
- 'holder_document' => preg_replace('/\D+/', '', $bankAccountData['holder_document']),
- 'bank' => $bankAccountData['bank'],
- 'branch_number' => $bankAccountData['branch_number'],
- 'branch_check_digit' => $bankAccountData['branch_check_digit'] ?? null,
- 'account_number' => $bankAccountData['account_number'],
- 'account_check_digit' => $bankAccountData['account_check_digit'],
- 'type' => $bankAccountData['type'],
- ],
- 'transfer_settings' => [
- 'transfer_enabled' => false,
- 'transfer_interval' => 'Daily',
- 'transfer_day' => 0,
- ],
- 'automatic_anticipation_settings' => [
- 'enabled' => false,
- ],
- ]);
- $response = $this->pagarmeRequest($provider->id)
- ->post($this->pagarmeUrl('/recipients'), $payload);
- if ($response->failed()) {
- Log::channel('pagarme')->error('Pagar.me recipient creation failed', [
- 'status' => $response->status(),
- 'body' => $response->json() ?? $response->body(),
- 'payload' => $payload,
- ]);
- throw new \RuntimeException('Erro ao criar recebedor no Pagar.me.');
- }
- $recipientData = $response->json();
- $recipientId = $recipientData['id'] ?? null;
- if (! $recipientId) {
- Log::channel('pagarme')->error('Pagar.me recipient creation returned empty id', [
- 'response' => $recipientData,
- ]);
- throw new \RuntimeException('Pagar.me recipient creation returned an empty id.');
- }
- $provider->forceFill([
- 'recipient_id' => $recipientId,
- 'recipient_name' => $data['recipient_name'],
- 'recipient_email' => $data['recipient_email'],
- 'recipient_description' => $data['recipient_description'],
- 'recipient_document' => $data['recipient_document'],
- 'recipient_type' => $recipientType,
- 'recipient_code' => $data['recipient_code'],
- 'recipient_payment_mode' => $paymentMode,
- 'recipient_default_bank_account' => $bankAccountData,
- 'recipient_transfer_settings' => [
- 'transfer_enabled' => false,
- 'transfer_interval' => 'daily',
- 'transfer_day' => 0,
- ],
- 'recipient_automatic_anticipation_settings' => [
- 'enabled' => false,
- ],
- 'recipient_metadata' => $metadata,
- ])->save();
- $this->applyAutomaticAnticipationSettings($provider->id, $recipientId);
- return $recipientId;
- }
- //
- private function pagarmeUrl(string $path): string
- {
- return rtrim(config('services.pagarme.base_url'), '/').'/'.ltrim($path, '/');
- }
- private function idempotencyKey(int $providerId, string $suffix = 'recipient'): string
- {
- return "provider-{$providerId}-{$suffix}";
- }
- //
- private function pagarmeRequest(int $providerId, string $suffix = 'recipient')
- {
- $secretKey = config('services.pagarme.secret_key');
- if (empty($secretKey)) {
- Log::channel('pagarme')->error('PAGARME_SECRET_KEY is not configured.');
- throw new \RuntimeException('PAGARME_SECRET_KEY is not configured.');
- }
- return Http::withBasicAuth($secretKey, '')
- ->withHeaders([
- 'Idempotency-Key' => $this->idempotencyKey($providerId, $suffix),
- 'Content-Type' => 'application/json',
- 'Accept' => 'application/json',
- ]);
- }
- private function applyAutomaticAnticipationSettings(int $providerId, string $recipientId): void
- {
- $payload = [
- 'enabled' => false,
- ];
- $response = $this->pagarmeRequest($providerId, 'auto-anticipation')
- ->patch($this->pagarmeUrl("/recipients/{$recipientId}/automatic-anticipation-settings"), $payload);
- if ($response->failed()) {
- Log::channel('pagarme')->error('Pagar.me automatic anticipation settings update failed', [
- 'status' => $response->status(),
- 'body' => $response->json() ?? $response->body(),
- 'payload' => $payload,
- ]);
- throw new \RuntimeException('Erro ao atualizar antecipação automática do recebedor no Pagar.me.');
- }
- }
- private function extractAddressParts(array $data): array
- {
- $addressLine = trim((string) ($data['address'] ?? ''));
- $segments = array_map('trim', explode(',', $addressLine));
- $streetSegment = $segments[0] ?? '';
- $streetNumber = $data['number'] ?? null;
- $neighborhood = $data['district'] ?? null;
- $referencePoint = $data['reference_point'] ?? null;
- $complementary = $data['complement'] ?? null;
- if ($streetNumber === null) {
- preg_match('/^(\d+)/', $streetSegment, $matches);
- $streetNumber = $matches[1] ?? 'S/N';
- }
- if ($neighborhood === null) {
- $neighborhood = $segments[1] ?? 'N/A';
- }
- if ($referencePoint === null) {
- $referencePoint = 'N/A';
- }
- if ($complementary === null) {
- $complementary = 'N/A';
- }
- return [
- 'street_number' => (string) $streetNumber,
- 'neighborhood' => (string) $neighborhood,
- 'reference_point' => (string) $referencePoint,
- 'complementary' => (string) $complementary,
- ];
- }
- private function buildPhoneNumbers(?string $phone): array
- {
- $digits = preg_replace('/\D+/', '', (string) $phone) ?? '';
- if (strlen($digits) < 10) {
- return [[
- 'ddd' => '11',
- 'number' => '999999999',
- 'type' => 'mobile',
- ]];
- }
- if (str_starts_with($digits, '55')) {
- $digits = substr($digits, 2);
- }
- $areaCode = substr($digits, 0, 2);
- $number = substr($digits, 2);
- return [[
- 'ddd' => $areaCode,
- 'number' => $number,
- 'type' => 'mobile',
- ]];
- }
- /**
- * @param array<string, mixed> $data
- * @return array<string, mixed>
- */
- private function filterFilledRecursive(array $data): array
- {
- $filtered = [];
- foreach ($data as $key => $value) {
- if (is_array($value)) {
- $value = $this->filterFilledRecursive($value);
- }
- if ($value !== null && $value !== '' && $value !== []) {
- $filtered[$key] = $value;
- }
- }
- return $filtered;
- }
- }
|