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 = [ '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', ]]; } }