PagarmePaymentService.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. namespace App\Services\Pagarme;
  3. use App\Data\Pagarme\Request\PagarmeCustomerRequestData\PagarmeCustomerRequestData;
  4. use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderItemData;
  5. use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderPaymentData\PagarmeOrderCreditCardData;
  6. use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderPaymentData\PagarmeOrderPaymentData;
  7. use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderPaymentData\PagarmeOrderPixData;
  8. use App\Data\Pagarme\Request\PagarmeOrderRequestData\PagarmeOrderRequestData;
  9. use App\Data\Pagarme\Response\PagarmeOrderResponseData\PagarmeOrderResponseData;
  10. use App\Enums\PaymentSplitStatusEnum;
  11. use App\Enums\PaymentStatusEnum;
  12. use App\Models\Payment;
  13. use App\Models\PaymentSplit;
  14. use App\Services\Pagarme\Concerns\SendsPagarmeRequests;
  15. use Illuminate\Support\Str;
  16. class PagarmePaymentService
  17. {
  18. use SendsPagarmeRequests;
  19. public function createOrderWithCreditCard(
  20. Payment $payment,
  21. array $items,
  22. PagarmeCustomerRequestData $customer,
  23. PagarmeOrderCreditCardData $creditCard,
  24. array $options = []
  25. ): array {
  26. return $this->createOrder(
  27. payment: $payment,
  28. items: $items,
  29. customer: $customer,
  30. paymentMethod: PagarmeOrderRequestData::creditCardPaymentMethod(
  31. creditCard: $creditCard,
  32. split: is_array($options['split'] ?? null) ? $options['split'] : null,
  33. ),
  34. options: $options,
  35. );
  36. }
  37. public function createOrderWithPix(
  38. Payment $payment,
  39. array $items,
  40. PagarmeCustomerRequestData $customer,
  41. PagarmeOrderPixData $pix,
  42. array $options = []
  43. ): array {
  44. return $this->createOrder(
  45. payment: $payment,
  46. items: $items,
  47. customer: $customer,
  48. paymentMethod: PagarmeOrderRequestData::pixPaymentMethod(
  49. pix: $pix,
  50. split: is_array($options['split'] ?? null) ? $options['split'] : null,
  51. ),
  52. options: $options,
  53. );
  54. }
  55. // criacao de pedidos por metodo de pagamento
  56. public function createOrder(
  57. Payment $payment,
  58. array $items,
  59. PagarmeCustomerRequestData $customer,
  60. PagarmeOrderPaymentData $paymentMethod,
  61. array $options = []
  62. ): array {
  63. $metadata = array_merge([
  64. 'payment_id' => (string) $payment->id,
  65. 'schedule_id' => (string) $payment->schedule_id,
  66. 'client_id' => (string) $payment->client_id,
  67. 'provider_id' => (string) $payment->provider_id,
  68. ], $options['metadata'] ?? []);
  69. $requestData = new PagarmeOrderRequestData(
  70. code: $this->ensurePaymentCode($payment),
  71. items: $items,
  72. payments: [$paymentMethod],
  73. metadata: $metadata,
  74. customer: $customer,
  75. customerId: $options['customer_id'] ?? null,
  76. closed: $options['closed'] ?? true,
  77. channel: $options['channel'] ?? null,
  78. );
  79. $order = PagarmeOrderResponseData::fromArray($this->pagarmeRequest(
  80. method: 'POST',
  81. path: '/orders',
  82. payload: $requestData,
  83. idempotencyKey: $this->idempotencyKey($payment),
  84. errorMessage: 'Erro ao criar pedido de pagamento no Pagar.me.',
  85. ));
  86. $order->requireId();
  87. return $order->toArray();
  88. }
  89. // evita criacao duplicada de pedidos
  90. private function idempotencyKey(Payment $payment): string
  91. {
  92. return "payment-{$payment->id}-schedule-{$payment->schedule_id}";
  93. }
  94. private function ensurePaymentCode(Payment $payment): string
  95. {
  96. if (! empty($payment->gateway_code)) {
  97. return $payment->gateway_code;
  98. }
  99. $code = 'payment-'.(string) Str::uuid();
  100. $payment->forceFill(['gateway_code' => $code])->save();
  101. return $code;
  102. }
  103. //
  104. public function applyGatewayResponseToPayment(Payment $payment, array $orderResponse): Payment
  105. {
  106. $order = PagarmeOrderResponseData::fromArray($orderResponse);
  107. $newStatus = $order->paymentStatus();
  108. $failureCode = null;
  109. $failureMessage = null;
  110. if ($newStatus === PaymentStatusEnum::FAILED) {
  111. $failureCode = $order->failureCode();
  112. $failureMessage = $order->failureMessage();
  113. }
  114. $payment->forceFill([
  115. 'gateway_provider' => 'pagarme',
  116. 'gateway_entity_reference' => $order->gatewayEntityReference(),
  117. 'gateway_entity_label' => $order->gatewayEntityLabel(),
  118. 'gateway_operation_reference' => $order->gatewayOperationReference(),
  119. 'gateway_operation_label' => $order->gatewayOperationLabel(),
  120. 'status' => $newStatus,
  121. 'paid_at' => $order->paidAt(),
  122. 'authorized_at' => $order->authorizedAt(),
  123. 'gateway_payload' => $orderResponse,
  124. 'failure_code' => $failureCode,
  125. 'failure_message' => $failureMessage,
  126. ])->save();
  127. $splitStatus = match ($newStatus) {
  128. PaymentStatusEnum::PAID => PaymentSplitStatusEnum::TRANSFERRED,
  129. PaymentStatusEnum::FAILED => PaymentSplitStatusEnum::FAILED,
  130. PaymentStatusEnum::CANCELLED => PaymentSplitStatusEnum::CANCELLED,
  131. PaymentStatusEnum::AUTHORIZED => PaymentSplitStatusEnum::PROCESSING,
  132. default => PaymentSplitStatusEnum::PENDING,
  133. };
  134. PaymentSplit::query()
  135. ->where('payment_id', $payment->id)
  136. ->update(['status' => $splitStatus]);
  137. return $payment->fresh();
  138. }
  139. }