paymentModel = new PaymentModel(); $this->cprModel = new CprModel(); $this->b3Service = new B3CprService(); } public function __invoke(ServerRequestInterface $request) { $body = json_decode((string)$request->getBody(), true) ?? []; $paymentId = isset($body['payment_id']) ? (int)$body['payment_id'] : 0; if ($paymentId <= 0) { return ResponseLib::sendFail('payment_id inválido', [], 'E_VALIDATE')->withStatus(400); } $payment = $this->paymentModel->findById($paymentId); if (!$payment) { return ResponseLib::sendFail('Pagamento não encontrado', [], 'E_NOT_FOUND')->withStatus(404); } $statusId = (int)($payment['status_id'] ?? 0); if ($statusId === 0) { return ResponseLib::sendFail('Pagamento ainda não confirmado', ['payment_id' => $paymentId], 'E_PAYMENT_PENDING')->withStatus(409); } if ($statusId !== 1) { return ResponseLib::sendFail('Pagamento em status inválido', ['status_id' => $statusId], 'E_PAYMENT_STATUS')->withStatus(409); } $cpr = $this->cprModel->findByPaymentId($paymentId); if (!$cpr) { return ResponseLib::sendFail('Nenhuma CPR vinculada ao pagamento', [], 'E_CPR_NOT_FOUND')->withStatus(404); } try { $payload = $this->b3Service->mapToB3($cpr); $token = $this->resolveB3Token($request, $body); $result = $this->b3Service->postCpr($token, $payload); } catch (\Throwable $e) { return ResponseLib::sendFail('Falha ao enviar CPR à B3: ' . $e->getMessage(), [], 'E_EXTERNAL')->withStatus(502); } if (isset($result['error'])) { return ResponseLib::sendFail('cURL error during B3 CPR request', ['error' => $result['error']], 'E_EXTERNAL')->withStatus(502); } return ResponseLib::sendOk([ 'message' => 'CPR gerada com sucesso', 'payment_id' => $paymentId, 'b3_response' => $result['json'] ?? ($result['raw'] ?? null), ], 'S_CPR_SENT'); } private function resolveB3Token(ServerRequestInterface $request, array $body): string { $token = $body['b3_access_token'] ?? ($body['access_token'] ?? null); if (!$token) { $b3Auth = $request->getHeaderLine('X-B3-Authorization') ?: ''; if (stripos($b3Auth, 'Bearer ') === 0) { $token = trim(substr($b3Auth, 7)); } } if (!$token) { $token = $request->getHeaderLine('X-B3-Access-Token') ?: null; } if (!$token) { $token = $this->b3Service->getAccessToken(); } return $token; } }