| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <?php
- namespace App\Services\Pagarme;
- use App\Data\Pagarme\Request\PagarmeCardRequestData\PagarmeCardBillingAddressData;
- use App\Data\Pagarme\Request\PagarmeCardRequestData\PagarmeCardRequestData;
- use App\Data\Pagarme\Response\PagarmeCardResponseData;
- use App\Models\Address;
- use App\Models\ClientPaymentMethod;
- use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
- use Illuminate\Support\Facades\Log;
- class PagarmeCardService
- {
- use SendsPagarmeRequests;
- public function __construct(
- private readonly PagarmeCustomerService $pagarmeCustomerService,
- ) {}
- public function createCardForPaymentMethod(ClientPaymentMethod $paymentMethod): ?string
- {
- if (! empty($paymentMethod->gateway_card_id)) {
- return $paymentMethod->gateway_card_id;
- }
- if (empty($paymentMethod->token)) {
- throw new \InvalidArgumentException('Token do cartao e obrigatorio para salvar cartao no Pagar.me.');
- }
- $paymentMethod->loadMissing('client.user');
- $customerId = $this->pagarmeCustomerService->createCustomerForClient(
- $paymentMethod->client,
- []
- );
- if (empty($customerId)) {
- throw new \RuntimeException('Cliente precisa ter customer_id do Pagar.me para salvar cartao.');
- }
- $cardData = PagarmeCardResponseData::fromArray($this->pagarmeRequest(
- method: 'POST',
- path: "/customers/{$customerId}/cards",
- payload: new PagarmeCardRequestData(
- token: $paymentMethod->token,
- label: $paymentMethod->card_name,
- billingAddress: $this->buildBillingAddress($paymentMethod),
- ),
- idempotencyKey: $this->idempotencyKey($paymentMethod),
- errorMessage: 'Erro ao salvar cartao no Pagar.me.',
- ));
- $cardId = $cardData->id();
- if (empty($cardId)) {
- Log::channel('pagarme')->error('Pagar.me card creation returned empty id', [
- 'client_payment_method_id' => $paymentMethod->id,
- 'client_id' => $paymentMethod->client_id,
- 'customer_id' => $customerId,
- 'response' => $cardData->toArray(),
- ]);
- throw new \RuntimeException('Pagar.me card creation returned an empty id.');
- }
- $paymentMethod->forceFill([
- 'gateway_card_id' => $cardId,
- 'brand' => $paymentMethod->brand ?: $cardData->brand(),
- 'last_four_digits' => $paymentMethod->last_four_digits ?: $cardData->lastFourDigits(),
- ])->save();
- return $cardId;
- }
- //
- private function idempotencyKey(ClientPaymentMethod $paymentMethod): string
- {
- return "client-payment-method-{$paymentMethod->id}-card";
- }
- //
- private function buildBillingAddress(ClientPaymentMethod $paymentMethod): PagarmeCardBillingAddressData
- {
- $address = Address::query()
- ->with(['city.state', 'state'])
- ->where('source', 'client')
- ->where('source_id', $paymentMethod->client_id)
- ->orderByDesc('is_primary')
- ->latest('id')
- ->first();
- if (! $address) {
- throw new \InvalidArgumentException('Cliente precisa ter endereco para salvar cartao no Pagar.me.');
- }
- $state = $address->state?->code ?? $address->city?->state?->code;
- $city = $address->city?->name;
- $line1 = implode(', ', array_filter([
- $address->number ?: 'S/N',
- $address->address,
- $address->district,
- ]));
- foreach ([
- 'estado' => $state,
- 'cidade' => $city,
- 'cep' => $this->digits($address->zip_code),
- 'endereco' => $line1,
- ] as $field => $value) {
- if ($value === null || $value === '') {
- throw new \InvalidArgumentException("Cliente precisa ter {$field} valido para salvar cartao no Pagar.me.");
- }
- }
- return new PagarmeCardBillingAddressData(
- line1: $line1,
- line2: $address->complement ?: $address->instructions,
- zipCode: $this->digits($address->zip_code),
- city: $city,
- state: $state,
- country: 'BR',
- );
- }
- private function digits(?string $value): string
- {
- return preg_replace('/\D+/', '', (string) $value) ?? '';
- }
- 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;
- }
- }
|