service = new B3CprService(); $this->cprModel = new CprModel(); $this->statusModel = new StatusModel(); $this->paymentModel = new PaymentModel(); } public function __invoke(ServerRequestInterface $request) { $body = json_decode((string)$request->getBody(), true); if (!is_array($body)) { return ResponseLib::sendFail('Invalid JSON body', [], 'E_VALIDATE')->withStatus(400); } $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; } $cpr = $body['cpr'] ?? null; if (!is_array($cpr)) { $hasCprKeys = false; foreach ($body as $k => $_) { if (is_string($k) && substr($k, 0, 4) === 'cpr_') { $hasCprKeys = true; break; } } if ($hasCprKeys) { $cpr = $body; } } if (!is_array($cpr)) { return ResponseLib::sendFail('Missing CPR payload (array) in body as cpr', [], 'E_VALIDATE')->withStatus(400); } $userId = (int)($request->getAttribute('api_user_id') ?? 0); if ($userId <= 0) { return ResponseLib::sendFail('Authenticated user not found', [], 'E_VALIDATE')->withStatus(401); } $companyId = (int)($request->getAttribute('api_company_id') ?? 0); if ($companyId <= 0) { return ResponseLib::sendFail('Authenticated company not found', [], 'E_VALIDATE')->withStatus(401); } $statusId = $this->statusModel->getIdByStatus('pending'); if ($statusId === null) { return ResponseLib::sendFail('Pending status not found', [], 'E_DATABASE')->withStatus(500); } try { $paymentExternalId = 'B3_DIRECT_' . time(); $paymentId = $this->paymentModel->create($paymentExternalId, $statusId, $userId); } catch (\Throwable $e) { return ResponseLib::sendFail('Failed to create payment record: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500); } try { $record = $this->cprModel->create($cpr, $statusId, $paymentId, $userId, $companyId); } catch (\InvalidArgumentException $e) { return ResponseLib::sendFail($e->getMessage(), [], 'E_VALIDATE')->withStatus(400); } catch (\Throwable $e) { return ResponseLib::sendFail('Failed to create CPR: ' . $e->getMessage(), [], 'E_DATABASE')->withStatus(500); } try { $payload = $this->service->mapToB3($cpr); if (!$token) { $token = $this->service->getAccessToken(); } $result = $this->service->postCpr($token, $payload); } catch (\Throwable $e) { return ResponseLib::sendFail('Failed to send CPR to 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); } $status = (int)($result['status'] ?? 200); if (isset($result['json'])) { return Response::json($result['json'])->withStatus($status ?: 200); } return Response::json(['raw' => $result['raw'] ?? null, 'status' => $status])->withStatus($status ?: 502); } }