| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- <?php
- namespace App\Services\Pagarme;
- use App\Data\Pagarme\Recipient\BankAccountUpdateRequestData;
- use App\Data\Pagarme\Recipient\Parts\Request\AddressData;
- use App\Data\Pagarme\Recipient\Parts\Request\AutomaticAnticipationSettingsData;
- use App\Data\Pagarme\Recipient\Parts\Request\BankAccountData;
- use App\Data\Pagarme\Recipient\Parts\Request\PhoneData;
- use App\Data\Pagarme\Recipient\Parts\Request\PhoneNumbersData;
- use App\Data\Pagarme\Recipient\Parts\Request\RegisterInformationData;
- use App\Data\Pagarme\Recipient\Parts\Request\TransferSettingsData;
- use App\Data\Pagarme\Recipient\RecipientRequestData;
- use App\Data\Pagarme\Recipient\RecipientResponseData;
- use App\Models\Provider;
- use App\Services\Pagarme\Concerns\FormatsPagarmeData;
- use App\Services\Pagarme\Concerns\MocksPagarmeRequests;
- use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
- class PagarmeRecipientService
- {
- use FormatsPagarmeData;
- use MocksPagarmeRequests;
- use SendsPagarmeRequests;
- public function createRecipientForProvider(Provider $provider, array $data): string
- {
- if (! empty($provider->recipient_id)) {
- return $provider->recipient_id;
- }
- $metadata = data_get($data, 'recipient_metadata', []);
- $paymentMode = data_get($data, 'recipient_payment_mode');
- $recipientCode = $provider->ensureGatewayCode();
- $addressParts = $this->extractAddressParts($data);
- $registerInformation = new RegisterInformationData(
- name: data_get($data, 'recipient_name'),
- email: data_get($data, 'recipient_email'),
- document: $this->digits(data_get($data, 'recipient_document')),
- type: data_get($data, 'recipient_type', 'individual'),
- birthdate: $this->formatBirthdate(data_get($data, 'birth_date')),
- monthlyIncome: data_get($data, 'monthly_income') !== null ? (int) data_get($data, 'monthly_income') : 1000,
- professionalOccupation: data_get($data, 'professional_occupation', 'autonomo'),
- phoneNumbers: new PhoneNumbersData(
- $this->buildRecipientPhone(data_get($data, 'phone')),
- ),
- address: new AddressData(
- street: data_get($addressParts, 'street'),
- complementary: data_get($addressParts, 'complementary'),
- streetNumber: data_get($addressParts, 'street_number'),
- neighborhood: data_get($addressParts, 'neighborhood'),
- city: data_get($data, 'city'),
- state: data_get($data, 'state'),
- zipCode: $this->digits(data_get($data, 'zip_code')),
- referencePoint: data_get($addressParts, 'reference_point'),
- ),
- );
- $defaultBankAccount = $this->buildRecipientBankAccount(
- data_get($data, 'recipient_default_bank_account'),
- );
- $payload = new RecipientRequestData(
- code: $recipientCode,
- registerInformation: $registerInformation,
- defaultBankAccount: $defaultBankAccount,
- transferSettings: new TransferSettingsData(
- transferEnabled: false,
- transferInterval: 'Daily',
- transferDay: 0,
- ),
- automaticAnticipationSettings: new AutomaticAnticipationSettingsData(
- enabled: true,
- type: '1025', // isso significa que vai ser feita de acordo com o delay (dias)
- delay: 1,
- ),
- );
- $bankAccountData = $payload->defaultBankAccount->toArray();
- if ($this->shouldMockPagarmeRequest()) {
- $recipientId = $this->mockPagarmeId('re', $provider->id);
- $provider->forceFill([
- 'recipient_id' => $recipientId,
- 'recipient_name' => data_get($data, 'recipient_name'),
- 'recipient_email' => data_get($data, 'recipient_email'),
- 'recipient_description' => data_get($data, 'recipient_description', ''),
- 'recipient_document' => data_get($data, 'recipient_document'),
- 'recipient_type' => $payload->registerInformation->type,
- 'recipient_code' => $recipientCode,
- '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' => true,
- 'type' => 'full',
- 'delay' => 1,
- ],
- 'recipient_metadata' => array_merge($metadata, ['mocked' => true]),
- ])->save();
- return $recipientId;
- }
- $raw = $this->pagarmeRequest(
- method: 'POST',
- path: '/recipients',
- payload: $payload,
- idempotencyKey: $this->idempotencyKey($provider, '', $data),
- errorMessage: 'Erro ao criar recebedor no Pagar.me.',
- );
- $recipientData = RecipientResponseData::fromArray($raw);
- $recipientId = $recipientData->requireId();
- $provider->forceFill([
- 'recipient_id' => $recipientId,
- 'recipient_name' => data_get($data, 'recipient_name'),
- 'recipient_email' => data_get($data, 'recipient_email'),
- 'recipient_description' => data_get($data, 'recipient_description', ''),
- 'recipient_document' => data_get($data, 'recipient_document'),
- 'recipient_type' => $payload->registerInformation->type,
- 'recipient_code' => $recipientCode,
- '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' => true,
- 'type' => 'full',
- 'delay' => 1,
- ],
- 'recipient_metadata' => $metadata,
- ])->save();
- return $recipientId;
- }
- public function updateDefaultBankAccount(Provider $provider, array $bankAccountData): Provider
- {
- $payload = new BankAccountUpdateRequestData(
- holderName: $this->normalizeHolderName(data_get($bankAccountData, 'holder_name')),
- holderType: data_get($bankAccountData, 'holder_type'),
- holderDocument: $this->digits(data_get($bankAccountData, 'holder_document')),
- bank: data_get($bankAccountData, 'bank'),
- branchNumber: data_get($bankAccountData, 'branch_number'),
- branchCheckDigit: data_get($bankAccountData, 'branch_check_digit'),
- accountNumber: data_get($bankAccountData, 'account_number'),
- accountCheckDigit: data_get($bankAccountData, 'account_check_digit'),
- type: data_get($bankAccountData, 'type'),
- );
- if ($this->shouldMockPagarmeRequest()) {
- $provider->forceFill([
- 'recipient_default_bank_account' => $payload->toArray()['bank_account'],
- ])->save();
- return $provider->fresh();
- }
- $this->pagarmeRequest(
- method: 'PATCH',
- path: "/recipients/{$provider->recipient_id}/default-bank-account",
- payload: $payload,
- idempotencyKey: $this->idempotencyKey($provider, 'default-bank-account-'.sha1(json_encode($payload->toArray()))),
- errorMessage: 'Erro ao atualizar conta bancaria do recebedor no Pagar.me.',
- );
- $provider->forceFill([
- 'recipient_default_bank_account' => $payload->toArray()['bank_account'],
- ])->save();
- return $provider->fresh();
- }
- //
- private function buildRecipientBankAccount(array $data): BankAccountData
- {
- return new BankAccountData(
- holderName: $this->normalizeHolderName(data_get($data, 'holder_name')),
- holderType: data_get($data, 'holder_type'),
- holderDocument: $this->digits(data_get($data, 'holder_document')),
- bank: data_get($data, 'bank'),
- branchNumber: data_get($data, 'branch_number'),
- branchCheckDigit: data_get($data, 'branch_check_digit'),
- accountNumber: data_get($data, 'account_number'),
- accountCheckDigit: data_get($data, 'account_check_digit'),
- type: data_get($data, 'type'),
- );
- }
- private function buildRecipientPhone(?string $phone): PhoneData
- {
- $digits = $this->digits($phone);
- if (strlen($digits) < 10) {
- return new PhoneData(
- ddd: '11',
- number: '999999999',
- type: 'mobile',
- );
- }
- if (str_starts_with($digits, '55')) {
- $digits = substr($digits, 2);
- }
- return new PhoneData(
- ddd: substr($digits, 0, 2),
- number: substr($digits, 2),
- type: 'mobile',
- );
- }
- // evita criacao duplica de recipient
- // formato: recipient-{email}-{documento} (tudo minusculo e sem acento)
- private function idempotencyKey(Provider $provider, string $suffix = '', array $data = []): string
- {
- $baseKey = $provider->idempotency_key;
- if (empty($baseKey)) {
- $provider->loadMissing('user');
- $baseKey = $this->pagarmeIdempotencyKey('recipient', [
- data_get($data, 'recipient_email', $provider->recipient_email ?? $provider->user?->email ?? "provider-{$provider->id}"),
- $this->customerDocument(data_get($data, 'recipient_document', $provider->recipient_document ?? $provider->document))
- ?: "document-provider-{$provider->id}",
- ]);
- $provider->forceFill(['idempotency_key' => $baseKey])->save();
- }
- return $suffix ? "{$baseKey}-{$suffix}" : $baseKey;
- }
- }
|