WooviWebhookController.php 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <?php
  2. namespace Controllers;
  3. use Libs\ResponseLib;
  4. use Models\PaymentModel;
  5. use Psr\Http\Message\ServerRequestInterface;
  6. class WooviWebhookController
  7. {
  8. private PaymentModel $paymentModel;
  9. public function __construct()
  10. {
  11. $this->paymentModel = new PaymentModel();
  12. }
  13. public function __invoke(ServerRequestInterface $request)
  14. {
  15. $rawBody = (string)$request->getBody();
  16. if ($rawBody === '') {
  17. $rawBody = (string)file_get_contents('php://input');
  18. }
  19. $payload = json_decode($rawBody, true);
  20. if (!is_array($payload)) {
  21. return ResponseLib::sendFail('Payload inválido', [], 'E_VALIDATE')->withStatus(400);
  22. }
  23. $charge = $payload['charge'] ?? null;
  24. if (!is_array($charge)) {
  25. return ResponseLib::sendFail('Charge inválida', [], 'E_VALIDATE')->withStatus(400);
  26. }
  27. $correlationId = $charge['correlationID'] ?? null;
  28. $status = $charge['status'] ?? null;
  29. if (!is_string($correlationId) || $correlationId === '') {
  30. return ResponseLib::sendFail('correlationID inválido', [], 'E_VALIDATE')->withStatus(400);
  31. }
  32. if (!is_string($status) || $status === '') {
  33. return ResponseLib::sendFail('status inválido', [], 'E_VALIDATE')->withStatus(400);
  34. }
  35. if (!$this->isPaidStatus($status)) {
  36. return ResponseLib::sendOk([
  37. 'correlation_id' => $correlationId,
  38. 'status' => $status,
  39. 'updated' => false,
  40. ], 'S_WEBHOOK_IGNORED');
  41. }
  42. try {
  43. $payment = $this->paymentModel->findByExternalId($correlationId);
  44. } catch (\Throwable $e) {
  45. return ResponseLib::sendFail('Falha ao consultar pagamento: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
  46. }
  47. if (!$payment) {
  48. return ResponseLib::sendFail('Pagamento não encontrado', ['correlation_id' => $correlationId], 'E_NOT_FOUND')->withStatus(404);
  49. }
  50. if ((int)($payment['status_id'] ?? 0) !== PaymentModel::STATUS_PENDING) {
  51. return ResponseLib::sendOk([
  52. 'payment_id' => (int)$payment['payment_id'],
  53. 'correlation_id' => $correlationId,
  54. 'status' => $status,
  55. 'status_id' => (int)($payment['status_id'] ?? 0),
  56. 'updated' => false,
  57. ], 'S_PAYMENT_ALREADY_UPDATED');
  58. }
  59. try {
  60. $this->paymentModel->updateStatusId((int)$payment['payment_id'], 1);
  61. } catch (\Throwable $e) {
  62. return ResponseLib::sendFail('Falha ao atualizar pagamento: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500);
  63. }
  64. return ResponseLib::sendOk([
  65. 'payment_id' => (int)$payment['payment_id'],
  66. 'correlation_id' => $correlationId,
  67. 'status' => $status,
  68. 'status_id' => 1,
  69. 'updated' => true,
  70. ], 'S_PAYMENT_UPDATED');
  71. }
  72. private function isPaidStatus(string $status): bool
  73. {
  74. $normalized = strtoupper(trim($status));
  75. return in_array($normalized, ['PAID', 'COMPLETED'], true);
  76. }
  77. }