PagarmePaymentService.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. $requestData = PagarmeOrderRequestData::fromOrderPayload(
  64. code: $this->ensurePaymentCode($payment),
  65. items: $items,
  66. customer: $customer,
  67. paymentMethod: $paymentMethod,
  68. metadata: array_merge([
  69. 'payment_id' => (string) $payment->id,
  70. 'schedule_id' => (string) $payment->schedule_id,
  71. 'client_id' => (string) $payment->client_id,
  72. 'provider_id' => (string) $payment->provider_id,
  73. ], $options['metadata'] ?? []),
  74. customerId: $options['customer_id'] ?? null,
  75. closed: $options['closed'] ?? true,
  76. channel: $options['channel'] ?? null,
  77. );
  78. $order = PagarmeOrderResponseData::fromArray($this->pagarmeRequest(
  79. method: 'POST',
  80. path: '/orders',
  81. payload: $requestData,
  82. idempotencyKey: $this->idempotencyKey($payment),
  83. errorMessage: 'Erro ao criar pedido de pagamento no Pagar.me.',
  84. ));
  85. $order->requireId();
  86. return $order->toArray();
  87. }
  88. // evita criacao duplicada de pedidos
  89. private function idempotencyKey(Payment $payment): string
  90. {
  91. return "payment-{$payment->id}-schedule-{$payment->schedule_id}";
  92. }
  93. private function ensurePaymentCode(Payment $payment): string
  94. {
  95. if (! empty($payment->gateway_code)) {
  96. return $payment->gateway_code;
  97. }
  98. $code = 'payment-'.(string) Str::uuid();
  99. $payment->forceFill(['gateway_code' => $code])->save();
  100. return $code;
  101. }
  102. //
  103. public function applyGatewayResponseToPayment(Payment $payment, array $orderResponse): Payment
  104. {
  105. $order = PagarmeOrderResponseData::fromArray($orderResponse);
  106. $newStatus = $order->paymentStatus();
  107. $failureCode = null;
  108. $failureMessage = null;
  109. if ($newStatus === PaymentStatusEnum::FAILED) {
  110. $failureCode = $order->failureCode();
  111. $failureMessage = $order->failureMessage();
  112. }
  113. $payment->forceFill([
  114. 'gateway_provider' => 'pagarme',
  115. 'gateway_entity_reference' => $order->gatewayEntityReference(),
  116. 'gateway_entity_label' => $order->gatewayEntityLabel(),
  117. 'gateway_operation_reference' => $order->gatewayOperationReference(),
  118. 'gateway_operation_label' => $order->gatewayOperationLabel(),
  119. 'status' => $newStatus,
  120. 'paid_at' => $order->paidAt(),
  121. 'authorized_at' => $order->authorizedAt(),
  122. 'gateway_payload' => $orderResponse,
  123. 'failure_code' => $failureCode,
  124. 'failure_message' => $failureMessage,
  125. ])->save();
  126. $splitStatus = match ($newStatus) {
  127. PaymentStatusEnum::PAID => PaymentSplitStatusEnum::TRANSFERRED,
  128. PaymentStatusEnum::FAILED => PaymentSplitStatusEnum::FAILED,
  129. PaymentStatusEnum::CANCELLED => PaymentSplitStatusEnum::CANCELLED,
  130. PaymentStatusEnum::AUTHORIZED => PaymentSplitStatusEnum::PROCESSING,
  131. default => PaymentSplitStatusEnum::PENDING,
  132. };
  133. PaymentSplit::query()
  134. ->where('payment_id', $payment->id)
  135. ->update(['status' => $splitStatus]);
  136. return $payment->fresh();
  137. }
  138. }