|
|
@@ -3,10 +3,19 @@
|
|
|
namespace App\Services\Pagarme;
|
|
|
|
|
|
use App\Data\Pagarme\Request\PagarmeBankAccountUpdateRequestData;
|
|
|
+use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientAddressData;
|
|
|
+use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientAutomaticAnticipationSettingsData;
|
|
|
+use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientBankAccountData;
|
|
|
+use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientPhoneData;
|
|
|
+use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientPhoneNumbersData;
|
|
|
+use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientRegisterInformationData;
|
|
|
use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientRequestData;
|
|
|
+use App\Data\Pagarme\Request\PagarmeRecipientRequestData\PagarmeRecipientTransferSettingsData;
|
|
|
+use App\Data\Pagarme\Response\PagarmeRecipientResponseData\PagarmeRecipientBankAccountResponseData;
|
|
|
use App\Data\Pagarme\Response\PagarmeRecipientResponseData\PagarmeRecipientResponseData;
|
|
|
use App\Models\Provider;
|
|
|
use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
|
|
|
+use Carbon\Carbon;
|
|
|
use Illuminate\Support\Str;
|
|
|
|
|
|
class PagarmeRecipientService
|
|
|
@@ -19,19 +28,69 @@ class PagarmeRecipientService
|
|
|
return $provider->recipient_id;
|
|
|
}
|
|
|
|
|
|
- $metadata = $data['recipient_metadata'] ?? [];
|
|
|
- $paymentMode = $data['recipient_payment_mode'];
|
|
|
+ $metadata = $data['recipient_metadata'] ?? [];
|
|
|
+ $paymentMode = $data['recipient_payment_mode'];
|
|
|
$recipientCode = $this->ensureRecipientCode($provider);
|
|
|
- $payload = PagarmeRecipientRequestData::fromPayload($recipientCode, $data);
|
|
|
+
|
|
|
+ $addressParts = $this->extractAddressParts($data);
|
|
|
+
|
|
|
+ $registerInformation = new PagarmeRecipientRegisterInformationData(
|
|
|
+ name: $data['recipient_name'],
|
|
|
+ email: $data['recipient_email'],
|
|
|
+ document: $this->onlyDigits($data['recipient_document'] ?? null),
|
|
|
+ type: $data['recipient_type'] ?? 'individual',
|
|
|
+ birthdate: $this->formatBirthdate($data['birth_date'] ?? null),
|
|
|
+ monthlyIncome: isset($data['monthly_income']) ? (int) $data['monthly_income'] : 1000,
|
|
|
+ professionalOccupation: $data['professional_occupation'] ?? 'autonomo',
|
|
|
+
|
|
|
+ phoneNumbers: new PagarmeRecipientPhoneNumbersData(
|
|
|
+ $this->buildRecipientPhone($data['phone'] ?? null),
|
|
|
+ ),
|
|
|
+
|
|
|
+ address: new PagarmeRecipientAddressData(
|
|
|
+ street: $data['address'],
|
|
|
+ complementary: $addressParts['complementary'],
|
|
|
+ streetNumber: $addressParts['street_number'],
|
|
|
+ neighborhood: $addressParts['neighborhood'],
|
|
|
+ city: $data['city'] ?? null,
|
|
|
+ state: $data['state'] ?? null,
|
|
|
+ zipCode: $this->onlyDigits($data['zip_code'] ?? null),
|
|
|
+ referencePoint: $addressParts['reference_point'],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+
|
|
|
+ $defaultBankAccount = $this->buildRecipientBankAccount(
|
|
|
+ $data['recipient_default_bank_account'],
|
|
|
+ );
|
|
|
+
|
|
|
+ $payload = new PagarmeRecipientRequestData(
|
|
|
+ code: $recipientCode,
|
|
|
+
|
|
|
+ registerInformation: $registerInformation,
|
|
|
+ defaultBankAccount: $defaultBankAccount,
|
|
|
+
|
|
|
+ transferSettings: new PagarmeRecipientTransferSettingsData(
|
|
|
+ transferEnabled: false,
|
|
|
+ transferInterval: 'Daily',
|
|
|
+ transferDay: 0,
|
|
|
+ ),
|
|
|
+
|
|
|
+ automaticAnticipationSettings: new PagarmeRecipientAutomaticAnticipationSettingsData(
|
|
|
+ enabled: false,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+
|
|
|
$bankAccountData = $payload->defaultBankAccount->toArray();
|
|
|
|
|
|
- $recipientData = PagarmeRecipientResponseData::fromArray($this->pagarmeRequest(
|
|
|
+ $raw = $this->pagarmeRequest(
|
|
|
method: 'POST',
|
|
|
path: '/recipients',
|
|
|
payload: $payload,
|
|
|
idempotencyKey: $this->idempotencyKey($provider->id),
|
|
|
errorMessage: 'Erro ao criar recebedor no Pagar.me.',
|
|
|
- ));
|
|
|
+ );
|
|
|
+
|
|
|
+ $recipientData = $this->buildRecipientResponse($raw);
|
|
|
|
|
|
$recipientId = $recipientData->requireId();
|
|
|
|
|
|
@@ -64,15 +123,27 @@ class PagarmeRecipientService
|
|
|
|
|
|
public function updateDefaultBankAccount(Provider $provider, array $bankAccountData): Provider
|
|
|
{
|
|
|
- $payload = PagarmeBankAccountUpdateRequestData::fromArray($bankAccountData);
|
|
|
+ $payload = new PagarmeBankAccountUpdateRequestData(
|
|
|
+ holderName: $this->normalizeHolderName($bankAccountData['holder_name']),
|
|
|
+ holderType: $bankAccountData['holder_type'],
|
|
|
+ holderDocument: $this->onlyDigits($bankAccountData['holder_document']),
|
|
|
+ bank: $bankAccountData['bank'],
|
|
|
+ branchNumber: $bankAccountData['branch_number'],
|
|
|
+ branchCheckDigit: $bankAccountData['branch_check_digit'] ?? null,
|
|
|
+ accountNumber: $bankAccountData['account_number'],
|
|
|
+ accountCheckDigit: $bankAccountData['account_check_digit'],
|
|
|
+ type: $bankAccountData['type'],
|
|
|
+ );
|
|
|
|
|
|
- $recipientData = PagarmeRecipientResponseData::fromArray($this->pagarmeRequest(
|
|
|
+ $raw = $this->pagarmeRequest(
|
|
|
method: 'PATCH',
|
|
|
path: "/recipients/{$provider->recipient_id}/default-bank-account",
|
|
|
payload: $payload,
|
|
|
idempotencyKey: $this->idempotencyKey($provider->id, 'default-bank-account-'.sha1(json_encode($payload->toArray()))),
|
|
|
errorMessage: 'Erro ao atualizar conta bancaria do recebedor no Pagar.me.',
|
|
|
- ));
|
|
|
+ );
|
|
|
+
|
|
|
+ $recipientData = $this->buildRecipientResponse($raw);
|
|
|
|
|
|
$provider->forceFill([
|
|
|
'recipient_default_bank_account' => $recipientData->defaultBankAccount()?->toArray() ?: $payload->toArray()['bank_account'],
|
|
|
@@ -81,6 +152,156 @@ class PagarmeRecipientService
|
|
|
return $provider->fresh();
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
+ private function buildRecipientBankAccount(array $data): PagarmeRecipientBankAccountData
|
|
|
+ {
|
|
|
+ return new PagarmeRecipientBankAccountData(
|
|
|
+ holderName: $this->normalizeHolderName($data['holder_name']),
|
|
|
+ holderType: $data['holder_type'],
|
|
|
+ holderDocument: $this->onlyDigits($data['holder_document']),
|
|
|
+ bank: $data['bank'],
|
|
|
+ branchNumber: $data['branch_number'],
|
|
|
+ branchCheckDigit: $data['branch_check_digit'] ?? null,
|
|
|
+ accountNumber: $data['account_number'],
|
|
|
+ accountCheckDigit: $data['account_check_digit'],
|
|
|
+ type: $data['type'],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private function buildRecipientPhone(?string $phone): PagarmeRecipientPhoneData
|
|
|
+ {
|
|
|
+ $digits = $this->onlyDigits($phone);
|
|
|
+
|
|
|
+ if (strlen($digits) < 10) {
|
|
|
+ return new PagarmeRecipientPhoneData(
|
|
|
+ ddd: '11',
|
|
|
+ number: '999999999',
|
|
|
+ type: 'mobile',
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ if (str_starts_with($digits, '55')) {
|
|
|
+ $digits = substr($digits, 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ return new PagarmeRecipientPhoneData(
|
|
|
+ ddd: substr($digits, 0, 2),
|
|
|
+ number: substr($digits, 2),
|
|
|
+ type: 'mobile',
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private function extractAddressParts(array $data): array
|
|
|
+ {
|
|
|
+ $addressLine = trim((string) ($data['address'] ?? ''));
|
|
|
+ $segments = array_map('trim', explode(',', $addressLine));
|
|
|
+ $streetSegment = $segments[0] ?? '';
|
|
|
+
|
|
|
+ if (($data['number'] ?? null) === null) {
|
|
|
+ preg_match('/^(\d+)/', $streetSegment, $matches);
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'street_number' => (string) ($data['number'] ?? $matches[1] ?? 'S/N'),
|
|
|
+ 'neighborhood' => (string) ($data['district'] ?? $segments[1] ?? 'N/A'),
|
|
|
+ 'reference_point' => (string) ($data['reference_point'] ?? 'N/A'),
|
|
|
+ 'complementary' => (string) ($data['complement'] ?? 'N/A'),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ private function formatBirthdate(mixed $birthdate): ?string
|
|
|
+ {
|
|
|
+ if ($birthdate === null || $birthdate === '') {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($birthdate instanceof \DateTimeInterface) {
|
|
|
+ return Carbon::instance($birthdate)->format('d/m/Y');
|
|
|
+ }
|
|
|
+
|
|
|
+ $birthdate = trim((string) $birthdate);
|
|
|
+
|
|
|
+ if (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $birthdate) === 1) {
|
|
|
+ return $birthdate;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $birthdate) === 1) {
|
|
|
+ return Carbon::createFromFormat('Y-m-d', $birthdate)->format('d/m/Y');
|
|
|
+ }
|
|
|
+
|
|
|
+ return Carbon::parse($birthdate)->format('d/m/Y');
|
|
|
+ }
|
|
|
+
|
|
|
+ private function normalizeHolderName(string $holderName): string
|
|
|
+ {
|
|
|
+ $holderName = trim(preg_replace('/\s+/', ' ', $holderName) ?? '');
|
|
|
+
|
|
|
+ if (Str::length($holderName) < 30) {
|
|
|
+ return $holderName;
|
|
|
+ }
|
|
|
+
|
|
|
+ $parts = explode(' ', $holderName);
|
|
|
+
|
|
|
+ if (count($parts) >= 3) {
|
|
|
+ $firstName = array_shift($parts);
|
|
|
+ $lastName = array_pop($parts);
|
|
|
+
|
|
|
+ $initials = array_map(
|
|
|
+ static fn (string $part): string => Str::upper(Str::substr($part, 0, 1)),
|
|
|
+ $parts
|
|
|
+ );
|
|
|
+
|
|
|
+ $abbreviated = trim($firstName.' '.implode(' ', $initials).' '.$lastName);
|
|
|
+
|
|
|
+ if (Str::length($abbreviated) < 30) {
|
|
|
+ return $abbreviated;
|
|
|
+ }
|
|
|
+
|
|
|
+ $firstAndLast = trim($firstName.' '.$lastName);
|
|
|
+
|
|
|
+ if (Str::length($firstAndLast) < 30) {
|
|
|
+ return $firstAndLast;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return Str::limit($holderName, 29, '');
|
|
|
+ }
|
|
|
+
|
|
|
+ private function buildRecipientResponse(array $raw): PagarmeRecipientResponseData
|
|
|
+ {
|
|
|
+ return new PagarmeRecipientResponseData(
|
|
|
+ id: $raw['id'] ?? null,
|
|
|
+ name: $raw['name'] ?? null,
|
|
|
+ email: $raw['email'] ?? null,
|
|
|
+ document: $raw['document'] ?? null,
|
|
|
+ type: $raw['type'] ?? null,
|
|
|
+ status: $raw['status'] ?? null,
|
|
|
+
|
|
|
+ defaultBankAccount: ! empty($raw['default_bank_account'])
|
|
|
+ ? new PagarmeRecipientBankAccountResponseData(
|
|
|
+ holderName: $raw['default_bank_account']['holder_name'] ?? null,
|
|
|
+ holderType: $raw['default_bank_account']['holder_type'] ?? null,
|
|
|
+ holderDocument: $raw['default_bank_account']['holder_document'] ?? null,
|
|
|
+ bank: $raw['default_bank_account']['bank'] ?? null,
|
|
|
+ branchNumber: $raw['default_bank_account']['branch_number'] ?? null,
|
|
|
+ branchCheckDigit: $raw['default_bank_account']['branch_check_digit'] ?? null,
|
|
|
+ accountNumber: $raw['default_bank_account']['account_number'] ?? null,
|
|
|
+ accountCheckDigit: $raw['default_bank_account']['account_check_digit'] ?? null,
|
|
|
+ type: $raw['default_bank_account']['type'] ?? null,
|
|
|
+ )
|
|
|
+ : null,
|
|
|
+
|
|
|
+ createdAt: $raw['created_at'] ?? null,
|
|
|
+ updatedAt: $raw['updated_at'] ?? null,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private function onlyDigits(?string $value): string
|
|
|
+ {
|
|
|
+ return preg_replace('/\D+/', '', (string) $value) ?? '';
|
|
|
+ }
|
|
|
+
|
|
|
// evita criacao duplica de recipient
|
|
|
|
|
|
private function idempotencyKey(int $providerId, string $suffix = 'recipient'): string
|