aeat.adapters.outbound.aeat.sede._groi_check module¶
AEAT GROI Spanish-ROI consult browser driver.
Drives the public AEAT-hosted GROI servlet that confirms whether a
given Spanish NIF is registered as an intra-community operator
(Registro de Operadores Intracomunitarios). The form accepts a
single 9-character Spanish NIF, posts to the same servlet path, and
renders a verdict text such as CONSTA UN OPERADOR INTRACOMUNITARIO
(registered) or no es un NIF válido (input-format error).
This adapter is the SPANISH-counterparty sibling of the IXVI
_nif_iva_check adapter (foreign-EU VIES proxy). Live probing on
2026-05-07 confirmed:
The GROI servlet at www2 is reachable under cl@ve-movil auth.
The IXVI servlet at www1 requires a stricter auth tier than cl@ve-movil and is currently blocked.
The two surfaces serve different verification needs:
GROI (this adapter): “is this Spanish NIF registered as an intra-community operator in Spain?” — used to confirm Spanish counterparties on modelo 349 are ROI-registered.
IXVI (
_nif_iva_check): “is this foreign EU IVA-ID valid per VIES?” — used to confirm foreign EU counterparties on modelo 349 hold a valid IVA identifier.
The driver reaches the form servlet directly via authenticated
BrowserSession (caller is responsible for loading the cl@ve-movil /
certificate storage state). Form selectors are verified against
captured live HTML (form action ConsultaOperadorSedeGroiServlet;
input id=nif name=nif maxlength=9; submit id=enviar
name=enviar); verdict markers are derived from real AEAT response
samples captured 2026-05-07.
- class GroiNifVerdict(**data)[source]¶
Bases:
_SedeCheckerModelOne observation per declared Spanish NIF after live navigation.
verdictis the AEAT-rendered ROI-registration status:validwhen AEAT reports the NIF as a registered intra-community operator,invalidwhen AEAT either says the NIF is unregistered or that the input format is malformed,unknownwhen the response text is structurally unanswerable.- Parameters:
- nif: str¶
- verdict: Literal['valid', 'invalid', 'unknown']¶
- raw_evidence_locator: str | None¶
- class GroiResult(**data)[source]¶
Bases:
_SedeCheckerModelAggregate live-driver result across every declared Spanish NIF.
- Parameters:
observations (tuple[GroiNifVerdict, ...])
- observations: tuple[GroiNifVerdict, ...]¶
- class GroiSedeDriver(*, settings=None)[source]¶
Bases:
objectLive AEAT GROI driver backed by the central BrowserSession surface.
The driver navigates directly to the form servlet (the surface is reachable post cl@ve-movil auth without an intermediate sede entry page) and queries each declared NIF in alphabetical order. Verdict parsing keys off the AEAT certification phrases captured live.
- Parameters:
settings (Settings | None)
- planned_operations(payload, *, expected)[source]¶
Return the ordered list of
RemoteOperationentries planned for this driver run.Builds the sequence: GET the GROI URL, open the form, then one
check-nif-<NIF>browser action per declared NIF (sorted alphabetically), and finallydiscard-session. At least one entry inexpectedis required; raisesRegistryValidationErrorotherwise.
- collect(payload, *, expected, timeout_ms=30000)[source]¶
Run the async GROI driver synchronously and return a
GroiResult.Wraps
collect_async()inasyncio.run.SedeError,SiteHealthError, andBrowserErrorare re-raised asRegistryValidationErrorfor the registry oracle layer.
- async collect_async(payload, *, expected, timeout_ms=30000)[source]¶
Async entry point returning
GroiResult— delegates tocollect_groi_observations().
- collect_observation(payload, *, expected)[source]¶
Return a
GroiObservationby adapting the per-NIF result into the registry-Protocol shape.Drives the live GROI form via
collect(), then collapses the per-NIF observations into a flat{nif: verdict}mapping that the GROI oracle wrapper compares against the caller’s expected verdicts.- Return type:
- Parameters:
- async collect_groi_observations(payload, *, expected, settings=None, timeout_ms=30000, browser_session_factory=None)[source]¶
Drive the GROI form per declared NIF and return a
GroiResultwith one observation each.