PagarmeOrderResponseData.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. namespace App\Data\Pagarme\Response\PagarmeOrderResponseData;
  3. use App\Enums\PaymentStatusEnum;
  4. /**
  5. * @param array<int, array> $items Itens do pedido (code, amount, quantity, description, etc.)
  6. * @param array<string, mixed>|null $customer Dados do cliente retornados pela API
  7. * @param array<int, array> $charges Cobrancas do pedido (status, amount, payment_method, last_transaction, etc.)
  8. * @param array<int, array> $checkouts Checkouts do pedido
  9. * @param array<string, mixed> $metadata Metadados retornados pela API
  10. */
  11. final readonly class PagarmeOrderResponseData
  12. {
  13. public function __construct(
  14. public ?string $id,
  15. public ?string $code,
  16. public ?int $amount,
  17. public ?string $currency,
  18. public ?bool $closed,
  19. public ?string $status,
  20. public array $items,
  21. public ?array $customer,
  22. public array $charges,
  23. public array $checkouts,
  24. public array $metadata,
  25. public ?string $createdAt = null,
  26. public ?string $updatedAt = null,
  27. public ?string $closedAt = null,
  28. ) {}
  29. public function authorizedAt(): ?string
  30. {
  31. $transaction = $this->lastTransaction();
  32. $transactionStatus = $transaction['status'] ?? null;
  33. if (in_array($transactionStatus, ['authorized_pending_capture', 'captured', 'partial_capture'], true)) {
  34. return $this->filledArrayValue($transaction, 'created_at');
  35. }
  36. return null;
  37. }
  38. public function failureCode(): ?string
  39. {
  40. return $this->filledArrayValue($this->lastTransaction()['gateway_response'] ?? [], 'code');
  41. }
  42. public function failureMessage(): ?string
  43. {
  44. $transaction = $this->lastTransaction();
  45. $acquirerMessage = $this->filledArrayValue($transaction, 'acquirer_message');
  46. if ($acquirerMessage) {
  47. return $acquirerMessage;
  48. }
  49. $gatewayErrors = $transaction['gateway_response']['errors'] ?? [];
  50. if (! is_array($gatewayErrors) || empty($gatewayErrors)) {
  51. return null;
  52. }
  53. $message = collect($gatewayErrors)
  54. ->pluck('message')
  55. ->filter()
  56. ->implode('; ') ?: null;
  57. if ($message && str_contains($message, 'Sem ambiente configurado')) {
  58. return 'Pix não esta habilitado ou configurado neste ambiente do Pagar.me.';
  59. }
  60. return $message;
  61. }
  62. public function firstCharge(): array
  63. {
  64. return $this->charges[0] ?? [];
  65. }
  66. public function gatewayEntityLabel(): string
  67. {
  68. return isset($this->firstCharge()['id']) ? 'charge' : 'order';
  69. }
  70. public function gatewayEntityReference(): ?string
  71. {
  72. $charge = $this->firstCharge();
  73. return $charge['id'] ?? $this->id;
  74. }
  75. public function gatewayOperationLabel(): string
  76. {
  77. $charge = $this->firstCharge();
  78. $transaction = $this->lastTransaction();
  79. return isset($transaction['id']) ? 'transaction' : (isset($charge['id']) ? 'charge' : 'order');
  80. }
  81. public function gatewayOperationReference(): ?string
  82. {
  83. $charge = $this->firstCharge();
  84. $transaction = $this->lastTransaction();
  85. return $transaction['id'] ?? $charge['id'] ?? $this->id;
  86. }
  87. public function id(): ?string
  88. {
  89. return $this->id;
  90. }
  91. public function lastTransaction(): array
  92. {
  93. return $this->firstCharge()['last_transaction'] ?? [];
  94. }
  95. public function paymentStatus(): PaymentStatusEnum
  96. {
  97. $charge = $this->firstCharge();
  98. $transaction = $this->lastTransaction();
  99. $status = strtolower((string) (($transaction['status'] ?? null) ?: ($charge['status'] ?? null)));
  100. return match ($status) {
  101. 'captured', 'paid', 'overpaid' => PaymentStatusEnum::PAID,
  102. 'authorized_pending_capture', 'waiting_capture' => PaymentStatusEnum::AUTHORIZED,
  103. 'pending', 'waiting_payment' => PaymentStatusEnum::PENDING,
  104. 'processing' => PaymentStatusEnum::PROCESSING,
  105. 'not_authorized', 'with_error', 'failed',
  106. 'underpaid', 'chargedback' => PaymentStatusEnum::FAILED,
  107. 'voided', 'partial_void', 'canceled',
  108. 'cancelled', 'refunded', 'partial_refunded',
  109. 'partial_canceled' => PaymentStatusEnum::CANCELLED,
  110. default => PaymentStatusEnum::PENDING,
  111. };
  112. }
  113. public function paidAt(): ?string
  114. {
  115. return $this->filledArrayValue($this->firstCharge(), 'paid_at');
  116. }
  117. public function requireId(): string
  118. {
  119. if (! $this->id) {
  120. throw new \RuntimeException('Pagar.me order creation returned an empty id.');
  121. }
  122. return $this->id;
  123. }
  124. //
  125. public static function fromArray(array $payload): self
  126. {
  127. return new self(
  128. id: $payload['id'] ?? null,
  129. code: $payload['code'] ?? null,
  130. amount: isset($payload['amount']) ? (int) $payload['amount'] : null,
  131. currency: $payload['currency'] ?? null,
  132. closed: $payload['closed'] ?? null,
  133. status: $payload['status'] ?? null,
  134. items: $payload['items'] ?? [],
  135. customer: ! empty($payload['customer']) ? $payload['customer'] : null,
  136. charges: $payload['charges'] ?? [],
  137. checkouts: $payload['checkouts'] ?? [],
  138. metadata: $payload['metadata'] ?? [],
  139. createdAt: $payload['created_at'] ?? null,
  140. updatedAt: $payload['updated_at'] ?? null,
  141. closedAt: $payload['closed_at'] ?? null,
  142. );
  143. }
  144. public function toArray(): array
  145. {
  146. return [
  147. 'id' => $this->id,
  148. 'code' => $this->code,
  149. 'amount' => $this->amount,
  150. 'currency' => $this->currency,
  151. 'closed' => $this->closed,
  152. 'items' => $this->items,
  153. 'customer' => $this->customer,
  154. 'status' => $this->status,
  155. 'created_at' => $this->createdAt,
  156. 'updated_at' => $this->updatedAt,
  157. 'closed_at' => $this->closedAt,
  158. 'charges' => $this->charges,
  159. 'checkouts' => $this->checkouts,
  160. 'metadata' => $this->metadata,
  161. ];
  162. }
  163. //
  164. private function filledArrayValue(array $data, string $field): ?string
  165. {
  166. if (! array_key_exists($field, $data) || $data[$field] === null || $data[$field] === '' || $data[$field] === []) {
  167. return null;
  168. }
  169. return (string) $data[$field];
  170. }
  171. }