RUC Verification¶
A RUC (Registro Único de Contribuyentes) is a Panamanian taxpayer ID. Before submitting an invoice, we verify the receiver's RUC against the DGI via Alanube. This:
- Catches typos before they get rejected at the DGI step.
- Returns the correct DV (verification digit).
- Determines whether the receiver is a
CONTRIBUYENTE,GOBIERNO, orCONSUMIDOR_FINAL.
The service¶
app/wrappers/pac/ruc_verification_service.py
contributor_type is NATURAL (individual) or JURIDICO (legal entity).
Endpoint¶
Response (relevant fields):
| Field | Meaning |
|---|---|
checkDigit |
The DV. Two digits. Used by InformacionReceptor.dv. |
receiver |
The receptor type from Alanube's perspective. Mapped by map_receiver_to_receptor_fe_type. |
type |
The contributor type echoed back. |
Mapping to ReceptorFeType¶
Alanube receiver |
Cifras ReceptorFeType |
|---|---|
CONTRIBUYENTE |
CONTRIBUYENTE |
GOBIERNO |
GOBIERNO |
| anything else (or unknown) | CONSUMIDOR_FINAL |
CONSUMIDOR_FINAL is the catch-all for individual end-customers without a registered RUC.
Where it's called¶
InvoicePacService._resolve_ruc_types— before building the PAC payload, for both invoices and credit notes.- Optionally exposed through GraphQL for client-side verification before form submission (check the
dgiGraphQL module for the public-facing query).
Retry behavior¶
verify_ruc is wrapped with tenacity:
- 2 attempts.
- Exponential backoff between 2s and 10s.
- Retries only on
aiohttp.ClientError. A 400 response (RUC not found) is not retried.
Ad-hoc RUC verification¶
When an invoice is issued to someone other than the registered client, the mutation can set:
adhoc_client_nameadhoc_client_ruc
In that case, _resolve_ruc_types verifies the ad-hoc RUC, not the client's. This lets you bill someone outside the master client list without permanently registering them.