model = new TshieldWebhookModel(); } public function __invoke(ServerRequestInterface $request) { $body = json_decode((string)$request->getBody(), true); if (!is_array($body)) { return ResponseLib::sendFail('Invalid JSON payload.', [], 'E_VALIDATE')->withStatus(400); } $statusDescription = $body['status']['status'] ?? null; if ($statusDescription !== 'Aprovado') { return ResponseLib::sendOk([ 'processed' => false, 'reason' => 'Status not approved. No action taken.', ], 'S_IGNORED'); } $number = $body['number'] ?? null; $token = $body['token'] ?? null; $cpf = $body['cpf'] ?? null; $cnpj = $body['cnpj'] ?? null; $externalCandidates = []; if (is_string($number) && trim($number) !== '') { $externalCandidates[] = $number; } if (empty($externalCandidates) && (!is_string($cpf) || trim($cpf) === '') && (!is_string($cnpj) || trim($cnpj) === '')) { return ResponseLib::sendFail('Missing analysis identifiers (number/cpf/cnpj) in payload.', [], 'E_VALIDATE')->withStatus(400); } $updatedRows = 0; $matchedBy = null; if (!empty($externalCandidates)) { $updatedRows = $this->model->approveByExternalIds($externalCandidates); if ($updatedRows > 0) { $matchedBy = 'external_id'; } } if ($updatedRows === 0 && is_string($cpf) && trim($cpf) !== '') { $updatedRows = $this->model->approveByCpf($cpf); if ($updatedRows > 0) { $matchedBy = 'cpf'; } } if ($updatedRows === 0 && is_string($cnpj) && trim($cnpj) !== '') { $updatedRows = $this->model->approveCompanyOwnerByCnpj($cnpj); if ($updatedRows > 0) { $matchedBy = 'cnpj_company_owner'; } } if ($updatedRows === 0) { return ResponseLib::sendFail( 'No user found to update KYC for this webhook payload.', [ 'number' => $number, 'token' => $token, 'cpf' => $cpf, 'cnpj' => $cnpj, ], 'E_NOT_FOUND' )->withStatus(404); } return ResponseLib::sendOk([ 'processed' => true, 'updated_rows' => $updatedRows, 'matched_by' => $matchedBy, 'number' => $number, 'token' => $token, ]); } }