Saltar al contenido principal

FEL certifier registry

FlowPOS separates SAT reference data, merchant configuration, and document certification results. The billing screen certifier dropdown is not a full dump of the database table—it lists only certifiers FlowPOS can certify against today.


Three layers

LayerStoragePurpose
Registryfel_certifierOfficial SAT certifier slug, legal name, and NIT per country
Merchant configbusiness.fel_certifier_config JSONBSelected slug + encrypted credentials
Document resultsale, order_bill, credit_note, debit_noteCertifier name/NIT returned at certification time

There is no foreign key from business to fel_certifier. The slug in felCertifierConfig.felCertifier is validated against both the integrated allowlist and the registry at save time.


Registry vs integrated (why the dropdown shows one option)

Guatemala has many SAT-authorized FEL certifiers. The migration seeds all of them into fel_certifier for reference (legal names, NITs, receipts). FlowPOS only integrates with certifiers that have a wired API adapter and production URL.

flowchart LR
DB["fel_certifier\n~18 SAT rows"]
API["GET /fel/certifiers"]
Allow["FEL_INTEGRATED_CERTIFIER_SLUGS"]
PWA["FelCredentialsSection\nfilter isIntegrated"]
Select["Billing dropdown"]

DB --> API
Allow --> API
API -->|"isIntegrated flag"| PWA --> Select
QuestionAnswer
Why does SELECT * FROM fel_certifier return many rows?The table is the full SAT registry for display and print normalization.
Why does the PWA dropdown show one certifier?The UI filters to isIntegrated === true. Only integrated slugs are selectable.
What happens if I pick a non-integrated slug via API?PATCH /businesses/:id/bill rejects it: "FEL certifier '…' is not integrated for certification yet".

Integrated allowlist (source of truth)

File: packages/global/consts/fel-integrated-certifiers.const.ts

Currently integrated:

SlugLegal name (registry)API URL configured
digifactDIGIFACT SERVICIOS, S. A.Yes (GuatemalanCertifiersUrls)

Not integrated yet (examples):

Slug / caseReason
infileEnum exists for legacy configs; excluded from allowlist until a real Infile URL is set in certifiers-urls.const.ts.
All other registry rows (Innova, Megaprint, Tekra, …)Row exists in fel_certifier only; no provider adapter or URL in FlowPOS yet.

Backend sets isIntegrated per row:

isIntegrated: isFelIntegratedCertifierSlug(row.name)

PWA billing (FelCredentialsSection) loads the API and filters client-side:

const rows = await listFelCertifiers(token!, countryId);
return rows.filter((row) => row.isIntegrated);

Merchant-facing explanation: FEL setup — certifier selection.


API

List certifiers

GET /fel/certifiers?countryId=GT

Returns every registry row for the country, each with isIntegrated: true | false. Example shape:

{
"id": "56730a25-9ced-43df-8de9-7924af1558f9",
"name": "digifact",
"legalName": "DIGIFACT SERVICIOS, S. A.",
"taxId": "77454820",
"countryId": "GT",
"isIntegrated": true
}

The billing screen uses integrated rows only. Other consumers (admin tools, future UI) may show the full list.

Save billing config

PATCH /businesses/:id/bill validates felCertifier via FelCertifierService.validateIntegratedSlug (allowlist + registry row must exist).


Backend code resolves display fields with resolveFelCertifierDisplayFields:

  1. When the merchant's certifier slug maps to a fel_certifier row, use the registry legal name (official SAT name, e.g. DIGIFACT SERVICIOS, S. A.)
  2. Use the certified NIT from the API when present, otherwise the registry NIT
  3. When no registry row is available, fall back to persisted API/document values

Certifier APIs sometimes return verbose spellings (e.g. DIGIFACT SERVICIOS, SOCIDAD ANONIMA); receipts and new certifications use the registry name instead.

This applies to sales (event handler), restaurant bills, credit/debit notes, and document-print payloads.


Adding a new integrated certifier

  1. Seed or verify the row in fel_certifier (migration or manual insert).
  2. Add the provider adapter and URL in the backend FEL module (ProviderService, GuatemalanCertifiersUrls, infrastructure adapter).
  3. Add the slug to FEL_INTEGRATED_CERTIFIER_SLUGS in fel-integrated-certifiers.const.ts.
  4. Map the slug in mapProviderNameToRpaFormat if using RPAfelApi.
  5. Verify the billing dropdown shows the new option and bill-save succeeds in staging.

See also: FEL Provider Port.