PagarmePaymentService.php 5.2 KB

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