| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- <?php
- namespace App\Services\Pagarme;
- use App\Data\Pagarme\Request\PagarmeCustomerRequestData\PagarmeCustomerRequestData;
- use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderItemData;
- use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderPaymentData\PagarmeOrderCreditCardData;
- use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderPaymentData\PagarmeOrderPaymentData;
- use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderPaymentData\PagarmeOrderPixData;
- use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderRequestData;
- use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerAddressResponseData;
- use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerPhonesResponseData\PagarmeCustomerPhonesResponseData;
- use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerPhonesResponseData\PagarmePhoneResponseData;
- use App\Data\Pagarme\Response\PagarmeCustomerResponseData\PagarmeCustomerResponseData;
- use App\Data\Pagarme\Response\PagarmeOrderResponseData\PagarmeOrderChargeResponseData\PagarmeOrderChargeResponseData;
- use App\Data\Pagarme\Response\PagarmeOrderResponseData\PagarmeOrderChargeResponseData\PagarmeOrderTransactionResponseData;
- use App\Data\Pagarme\Response\PagarmeOrderResponseData\PagarmeOrderCheckoutResponseData;
- use App\Data\Pagarme\Response\PagarmeOrderResponseData\PagarmeOrderItemResponseData;
- use App\Data\Pagarme\Response\PagarmeOrderResponseData\PagarmeOrderResponseData;
- use App\Enums\PaymentSplitStatusEnum;
- use App\Enums\PaymentStatusEnum;
- use App\Models\Payment;
- use App\Models\PaymentSplit;
- use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
- use Illuminate\Support\Str;
- class PagarmePaymentService
- {
- use SendsPagarmeRequests;
- public function createOrderWithCreditCard(
- Payment $payment,
- array $items,
- PagarmeCustomerRequestData $customer,
- PagarmeOrderCreditCardData $creditCard,
- array $options = []
- ): array {
- return $this->createOrder(
- payment: $payment,
- items: $items,
- customer: $customer,
- paymentMethod: PagarmeOrderRequestData::creditCardPaymentMethod(
- creditCard: $creditCard,
- split: is_array($options['split'] ?? null) ? $options['split'] : null,
- ),
- options: $options,
- );
- }
- public function createOrderWithPix(
- Payment $payment,
- array $items,
- PagarmeCustomerRequestData $customer,
- PagarmeOrderPixData $pix,
- array $options = []
- ): array {
- return $this->createOrder(
- payment: $payment,
- items: $items,
- customer: $customer,
- paymentMethod: PagarmeOrderRequestData::pixPaymentMethod(
- pix: $pix,
- split: is_array($options['split'] ?? null) ? $options['split'] : null,
- ),
- options: $options,
- );
- }
- // criacao de pedidos por metodo de pagamento
- public function createOrder(
- Payment $payment,
- array $items,
- PagarmeCustomerRequestData $customer,
- PagarmeOrderPaymentData $paymentMethod,
- array $options = []
- ): array {
- $metadata = array_merge([
- 'payment_id' => (string) $payment->id,
- 'schedule_id' => (string) $payment->schedule_id,
- 'client_id' => (string) $payment->client_id,
- 'provider_id' => (string) $payment->provider_id,
- ], $options['metadata'] ?? []);
- $requestData = new PagarmeOrderRequestData(
- code: $this->ensurePaymentCode($payment),
- items: $items,
- payments: [$paymentMethod],
- metadata: $metadata,
- customer: $customer,
- customerId: $options['customer_id'] ?? null,
- closed: $options['closed'] ?? true,
- channel: $options['channel'] ?? null,
- );
- $raw = $this->pagarmeRequest(
- method: 'POST',
- path: '/orders',
- payload: $requestData,
- idempotencyKey: $this->idempotencyKey($payment),
- errorMessage: 'Erro ao criar pedido de pagamento no Pagar.me.',
- );
- $order = $this->buildOrderResponse($raw);
- $order->requireId();
- return $order->toArray();
- }
- // evita criacao duplicada de pedidos
- private function idempotencyKey(Payment $payment): string
- {
- return "payment-{$payment->id}-schedule-{$payment->schedule_id}";
- }
- private function ensurePaymentCode(Payment $payment): string
- {
- if (! empty($payment->gateway_code)) {
- return $payment->gateway_code;
- }
- $code = 'payment-'.(string) Str::uuid();
- $payment->forceFill(['gateway_code' => $code])->save();
- return $code;
- }
- //
- public function applyGatewayResponseToPayment(Payment $payment, array $orderResponse): Payment
- {
- $order = $this->buildOrderResponse($orderResponse);
- $newStatus = $order->paymentStatus();
- $failureCode = null;
- $failureMessage = null;
- if ($newStatus === PaymentStatusEnum::FAILED) {
- $failureCode = $order->failureCode();
- $failureMessage = $order->failureMessage();
- }
- $payment->forceFill([
- 'gateway_provider' => 'pagarme',
- 'gateway_entity_reference' => $order->gatewayEntityReference(),
- 'gateway_entity_label' => $order->gatewayEntityLabel(),
- 'gateway_operation_reference' => $order->gatewayOperationReference(),
- 'gateway_operation_label' => $order->gatewayOperationLabel(),
- 'status' => $newStatus,
- 'paid_at' => $order->paidAt(),
- 'authorized_at' => $order->authorizedAt(),
- 'gateway_payload' => $orderResponse,
- 'failure_code' => $failureCode,
- 'failure_message' => $failureMessage,
- ])->save();
- $splitStatus = match ($newStatus) {
- PaymentStatusEnum::PAID => PaymentSplitStatusEnum::TRANSFERRED,
- PaymentStatusEnum::FAILED => PaymentSplitStatusEnum::FAILED,
- PaymentStatusEnum::CANCELLED => PaymentSplitStatusEnum::CANCELLED,
- PaymentStatusEnum::AUTHORIZED => PaymentSplitStatusEnum::PROCESSING,
- default => PaymentSplitStatusEnum::PENDING,
- };
- PaymentSplit::query()
- ->where('payment_id', $payment->id)
- ->update(['status' => $splitStatus]);
- return $payment->fresh();
- }
- //
- private function buildOrderResponse(array $raw): PagarmeOrderResponseData
- {
- return new PagarmeOrderResponseData(
- id: $raw['id'] ?? null,
- code: $raw['code'] ?? null,
- amount: isset($raw['amount']) ? (int) $raw['amount'] : null,
- currency: $raw['currency'] ?? null,
- closed: $raw['closed'] ?? null,
- status: $raw['status'] ?? null,
- items: array_map(
- fn (array $item) => new PagarmeOrderItemResponseData(
- id: $item['id'] ?? null,
- code: $item['code'] ?? null,
- amount: isset($item['amount']) ? (int) $item['amount'] : null,
- quantity: isset($item['quantity']) ? (int) $item['quantity'] : null,
- description: $item['description'] ?? null,
- status: $item['status'] ?? null,
- ),
- $raw['items'] ?? [],
- ),
- customer: ! empty($raw['customer'])
- ? $this->buildCustomerResponse($raw['customer'])
- : null,
- charges: array_map(
- fn (array $charge) => $this->buildChargeResponse($charge),
- $raw['charges'] ?? [],
- ),
- checkouts: array_map(
- fn (array $checkout) => new PagarmeOrderCheckoutResponseData(
- id: $checkout['id'] ?? null,
- status: $checkout['status'] ?? null,
- url: $checkout['url'] ?? null,
- ),
- $raw['checkouts'] ?? [],
- ),
- metadata: $raw['metadata'] ?? [],
- createdAt: $raw['created_at'] ?? null,
- updatedAt: $raw['updated_at'] ?? null,
- closedAt: $raw['closed_at'] ?? null,
- );
- }
- private function buildChargeResponse(array $raw): PagarmeOrderChargeResponseData
- {
- return new PagarmeOrderChargeResponseData(
- id: $raw['id'] ?? null,
- status: $raw['status'] ?? null,
- amount: isset($raw['amount']) ? (int) $raw['amount'] : null,
- currency: $raw['currency'] ?? null,
- paidAt: $raw['paid_at'] ?? null,
- createdAt: $raw['created_at'] ?? null,
- lastTransaction: ! empty($raw['last_transaction'])
- ? new PagarmeOrderTransactionResponseData(
- id: $raw['last_transaction']['id'] ?? null,
- status: $raw['last_transaction']['status'] ?? null,
- amount: isset($raw['last_transaction']['amount']) ? (int) $raw['last_transaction']['amount'] : null,
- createdAt: $raw['last_transaction']['created_at'] ?? null,
- acquirerMessage: $raw['last_transaction']['acquirer_message'] ?? null,
- gatewayResponse: $raw['last_transaction']['gateway_response'] ?? [],
- )
- : null,
- );
- }
- private function buildCustomerResponse(array $raw): PagarmeCustomerResponseData
- {
- return new PagarmeCustomerResponseData(
- id: $raw['id'] ?? null,
- name: $raw['name'] ?? null,
- email: $raw['email'] ?? null,
- code: $raw['code'] ?? null,
- document: $raw['document'] ?? null,
- documentType: $raw['document_type'] ?? null,
- type: $raw['type'] ?? null,
- delinquent: $raw['delinquent'] ?? null,
- address: ! empty($raw['address'])
- ? new PagarmeCustomerAddressResponseData(
- id: $raw['address']['id'] ?? null,
- line1: $raw['address']['line_1'] ?? null,
- line2: $raw['address']['line_2'] ?? null,
- zipCode: $raw['address']['zip_code'] ?? null,
- city: $raw['address']['city'] ?? null,
- state: $raw['address']['state'] ?? null,
- country: $raw['address']['country'] ?? null,
- status: $raw['address']['status'] ?? null,
- createdAt: $raw['address']['created_at'] ?? null,
- updatedAt: $raw['address']['updated_at'] ?? null,
- )
- : null,
- phones: new PagarmeCustomerPhonesResponseData(
- homePhone: ! empty($raw['phones']['home_phone'])
- ? new PagarmePhoneResponseData(
- countryCode: $raw['phones']['home_phone']['country_code'] ?? null,
- areaCode: $raw['phones']['home_phone']['area_code'] ?? null,
- number: $raw['phones']['home_phone']['number'] ?? null,
- )
- : null,
- mobilePhone: ! empty($raw['phones']['mobile_phone'])
- ? new PagarmePhoneResponseData(
- countryCode: $raw['phones']['mobile_phone']['country_code'] ?? null,
- areaCode: $raw['phones']['mobile_phone']['area_code'] ?? null,
- number: $raw['phones']['mobile_phone']['number'] ?? null,
- )
- : null,
- ),
- createdAt: $raw['created_at'] ?? null,
- updatedAt: $raw['updated_at'] ?? null,
- );
- }
- }
|